Event propogation whilst container is not initialised - apache-flex

I have a Canvas (lets call it the Drop Box) which users can drag and drop external files onto. Next to this I have a ViewStack, of which one of the layers is a Canvas with a TileList. I have successfully managed to code it so that the items dropped onto the Drop Box appear in the TileList. I simply capture the darg drop event (lets call this event A) and dispatch a new one that the TileList is listening for (lets call this event B).
However, this only works if the ViewStack selectedIndex is set to that of the Canvas with the TileList. If the Canvas with the TileList isn't selected then the event listener which is added to the TileList at CreationComplete level (event B), won't be called until after the drag drop event has dispatched (event B). This means that something is firing before something even has a chance to listen for it!
I've tried looping until the Canvas with the TileList is completely drawn, but this causes the app to hang.
I've also tried passing the event to the Canvas and storing it locally, but when I attempt to access the clipboad of the event I get an error (dead clipboard).
Effectively I want to only dispatch the event to the Canvas after it's had a chance to load, and add the event listener to the TileList.
Any ideas? :)

Maybe setting creationPolicy="all" for View Stack will help? All it's children will be created at startup.

Related

Mouse Listeners in Gluon

I've been trying to use listeners on gluon CharmListView for a while. It didn't work in my project so i decided to try it on the FIFTY STATES app. I added the code below:
charmListView.onMouseClickedProperty().set((MouseEvent event) ->{
Logger.getGlobal().log(Level.INFO, "Pick: {0}", new Object[]{event.getPickResult()});
});
When I launch the application, NO click fires aMOUSE_CLICKED event. When I scroll down slightly such that the a list header cell is fully docked like this,
the CharmListView fires the event only on a click on the top header cell.
INFO: Pick: PickResult [node = VBox#49f31558[styleClass=text-box], point = Point3D [x = 133.0, y = 13.0, z = 0.0], distance = 1067.366530964699
No other click anywhere else on the list fires an event.
I've tried adding the same listener to the normal ListView and a MouseEvent is always fired after a click on any area of the ListView. So now I'm stuck because I cannot set a listener to get a selected item.
The CharmListView control is mainly intended for mobile applications, where you use scroll and swipe gestures. But these gestures trigger mouse clicked or pressed events.
If the list cells contain some event handler to process the latter, the only way scroll works is by consuming them, otherwise whenever you scroll the list, the cell event handler will be processed as well, when you start scrolling.
That's the reason why setOnMouseClicked() doesn't trigger any event if you click on the listView.
For accessing the list view selection model, please refer to this question.

Why we use 'bubbles' in flex events

I've doubt when we create custom event in flex.
Why do we use 'type:String, bubbles:Boolean=false, cancelable:Boolean=false' these parameter in flex events.
Bubbling causes a dispatched event to continue to be dispatched up the display tree until it reaches the stage. This is useful in various scenarios.
For example: Imagine you have several buttons inside a parent DisplayObject. You could add listeners to each button, and remember to remove them afterwards, or you could just add one listener to the parent. This works because MouseEvents have bubbling enabled.
buttonParent.addEventListener(MouseEvent.CLICK,handleButtonClick);
function handleButtonClick(event:MouseEvent):void
{
trace("The button clicked was " + event.target.name);
}
The benefit of this is that you can now add and remove buttons freely, without having to worry about attaching listeners to them. The target property of the event object will be a reference to the button that was clicked, and currentTarget will be a reference to the parent.
Cancelable is a flag that sets whether or not you are permitted to stop the default action of an event by calling the preventDefault() method.

How does Flex click event work inside of containers?

I have a VBox, I assigned a handler to click, and inside the VBox I have components such as images and texts with no handler assigned for click. Would the click function be called when I click on the text and image? If not how can I make it so without assigning handlers individually, but on the container level?
Thanks
Click events "bubble" in Flex. When you click on an images, it bubbles up to its parent, then that parent's parent and so on until there are no more parents left.
If any of these have click listeners they will trigger when they are reached in the bubbling process.
Also in the event the currentTarget will refer to the object that has the listener, and the target will be what was actually clicked.
So in your case if they click the image, the event will bubble up to the container triggering the event, in your listener function the clicked image will be the event.target and the container will be the event.currentTarget.
Also in the bubbling process, it actually starts from the root parent down, this is called the capture phase, then bubbles back up. Your event will trigger when it bubbles back up unless you specify useCapturePhase = true in the event listener. This is how you can stop an event from going to its children. If you use the capture phase then call event.stopPropagation() inside the event listener then the container will receive the event but the child image will not.
It's taken an hour for an answer to this question... it probably would have been faster to just try it. :)
But yes, click events bubble up to parent containers. Adding the handler to the VBox should be fine.
I was pretty sure that containers, such as VBox do not dispatch click events; unless they are bubbled up from the children.
However, clicking on items in your container should trigger the listener on your container, as the Click event bubbles.

Flex Panel doesn't call focusInHandler() when it gets focus

I want to be notified when a FLex Panel gets or loses focus. I've overridden the focusInHandler() and the focusOutHandler(), but they don't get called when I click on the panel.
The panels style changes indicating that it has the focus, but the handler doesn't get called.
What am I missing?
Containers (and implicitly panels) aren't really focusable. Meaning that simply clicking on an empty container won't give it focus, and in consequence, won't trigger the event handler for "focusIn". In order for a container to "gain" focus, a child of that container, that implements IFocusManagerComponent interface, has to gain focus.
So if you want your panel to trigger the "focusIn" event when clicking on it, you should focus a focusable child of that panel on mouse click.
Have you tried to explicitly listen for that event:
myPanel.addEventListener(FocusEvent.FOCUS_IN, myEventHandler);
and made sure that it was getting called?

What the best way to coordinate loading initial values in syncronized Combo-Boxes & List Box

Environment: Flex/As3/Cairgorm/composite component.
I have two comboboxes and two datagrids such that the selection of combobox 1, inserts data into combobox two and the fist datagrid. The selection of combobox 2 inserts data into datagrid 2.
I have setup the change event so that the user selection on each of the combo boxes do the right thing. The problem is that on the initial load of the comboboxes, the change event does not fire and subsequent synchronization data loading does not happen.
Is there an event for getting the itemselected (1st item) after the combobox is initialized?
I found my own answer. Using the updateComplete event on each of the comboboxes did the trick.
[EDIT]
It turns out that updateComplete did not work as expected. What I really needed is the dataChange event. However, it appears that this event does not fire for comboboxes even though it is listed as a valid FlexEvent for this component.
I tried a number of other events (valueCommit, creationComplete, initialize) but all of these fire multiple times, overlap with change, and are not useful for this usecase.
In the end, I created a gludge of a chain of calls for the initialize path and change path.
If anyone else has a better way, I'd be very interested.

Resources