views:

111

answers:

3

Hi, I want to create a tab-enabled popup window in an AS3 Air project. Currently, when I press tab several times, the focus goes through all the components in my popup window and then starts focusing the buttons and TextFields from the components that are behind the popup. I have tried to solve this problem in two ways, but none of them worked. I will explain both of the methods here

  1. The official method
    I have read adobe's documentation from here and it describes what I should do in my case like this:

    "Each modal Window component contains an instance of the FocusManager, so the controls on that window become their own tab set. This prevents a user from inadvertently navigating to components in other windows by pressing the Tab key. " But I still don't understand how to use the FocusManager.

    • I have tried creating an instance of the FocusManager in each of my view component classes by putting the code below in the constructor, but it didn't work:

    _focusManager = new FocusManager(this);

    • What do they mean by "modal Window component" ?
  2. The workaround method
    Another thing I've tried is to manually set the tabEnabled property to true or false on each button and TextField when the Parent component dispatches a FOCUS_IN or FOCUS_OUT event. This worked on a simple example that I created on a new flash file, but it doesn't work on my large project, and I don't know how to debug it. However I would be very glad to dump this and go back to method number 1.

Has anyone encountered these problems before? Have you used multiple tab cycles in any other way? Any hint is welcome right now, because I've been wasting too much time on this problem. Thank you [Edit] I was getting a lot of views for this question, but no relevant answers, so I edited it and tried to simplify it

A: 

How do you init your FocusManager?

Eugene
Please note that I am using fl.managers.FocusManager and not the Flex equivalent mx.managers.FocusManager. And to answer your question.. I don't really understand what you mean by init.. if you mean calling the constructor then it's just _focusManager = new FocusManager(this) as I said before. And this throws a null pointer exception, so there is nothing else for me to init..
sssilviu
A: 

Depending on what you are trying to achieve, you maybe able to use tabIndex instead of the FocusManager.

http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/InteractiveObject.html#tabIndex

Trevor Boyle
Trevor, I already am using the tabIndex property. It's true that I haven't yet tried setting it to -1 whenever I set the tabEnabled property to false (in method number 2, the one with the stupid workaround) but I don't find this as the true solution to creating multiple tab loops. This is just a hack, it should work out of the box.
sssilviu
Are you only setting the tabIndex for your pop-up? "If any currently displayed object in the SWF file contains a tabIndex property, automatic tab ordering is disabled" which from my experience would prevent tabbing in the below components.
Trevor Boyle
When you display the pop-up, I would set the tabIndex for the pop-up objects, and then on hide, set them back to -1.
Trevor Boyle
If you require another tab order in your project, I would create a setTabOrder and resetTabOrder functions to enable and disable them.
Trevor Boyle
Trevor, sorry for the late reply, but I've been on vacation. I understand your point, and it makes perfect sense. It's almost exactly what I did in solution no 2 (The workaround method). But I have two arguments against it : 1. for some strange reason it doesn't work, 2. I don't really like to reimplement the tabbing mechanism, all I want is to find out how to correctly use the FocusManager
sssilviu
I am afraid that I have only used the above method and anything else that I have to offer would be untested stuff that I, and probably you have also, read. sorry.
Trevor Boyle
Having said that, this looks like a potential issue "All components that can be managed by a FocusManager instance must implement the fl.managers.IFocusManagerComponent interface" and the activate() and deactivate() methods look to be helpful... but as I said, I haven't used them before.
Trevor Boyle
A: 

I ended up writing my own FocusManager which does what I need. It turned out to be easier than I initially thought. I'm sorry to say that I can't post the code here, but I'll give you a short description of what I did and hope that it helps:

  • I implemented the fl.managers.IFocusManager interface, but I didn't entirely respect the way the old manager worked
  • The constructor of my CustomFocusManager requires an array of the tabbable children as parameter, and the children have to be in the order that they will appear in the loop. In this way I did not have to care about the type of the children (is it tabbable or not?) or ask myself if tabIndexes exist or not.
  • I ignored the tabIndex properties
  • I created a new interface called IFocusManagerContainer, inspired from the Flex interface with the same name
  • I created a static class similar to Flex's SystemManager which knows when to activate/deactivate the FocusManagers depending on the children found on the stage.

I took a peek into the mx.managers.FocusManager code, and from what I saw, most of their effort was put into handling all the possible cases where the FocusManager might be used, this is why it's so long and complicated. I can only assume that fl.managers.FocusManagers looks similar. I bet that mine still has a lot of problems, and it isn't as portable as the ones from Adobe, but it's very simple and it does what I need it to do.

I would still like to see some guidelines on how to correctly use the existing FocusManager.

sssilviu