views:

325

answers:

2

I've been creating a custom TabFolder extension that adds a key listener to allow quick tab switching using an ALT + # hotkey.

By adding the KeyAdapter to my TabFolder, the event handler works properly only when you have a tab header selected (in which case the ALT + ARROW_LEFT/ARROW_RIGHT also work.). I need this hot key to be active when any Widget with-in the TabFolder is active; however, it shouldn't be active if the selection is in a different tab folder or widget outside of a tab folder.

In an attempt to solve this, I wrote a simple recursive function to apply the key listener to all of the children of the tab folder:

public void applyQuickSwitchKeyBindings() {
    removeKeyListener(ka);
     addKeyListener(ka);
    for(Control c: getChildren())
        applyQuickSwitchKeyBindingsToChildren(c);

    }

private void applyQuickSwitchKeyBindingsToChildren(Control c) {

    if(c==null) return;
    if(c instanceof Composite) {
        Control[] controls = ((Composite)c).getChildren();
        for(Control c2: controls)
            applyQuickSwitchKeyBindingsToChildren(c2);
        if(controls.length < 1) {
            c.removeKeyListener(ka);
            c.addKeyListener(ka);
        }
    }
}

Then i call the applyQuickSwitchKeyBindings() after I add the controls to each TabItem in the tab group.

The good news was that the quick switch hot key (ALT + #) worked great!

The bad news was that the original TAB ordering based on z-index is now gone. When you hit the SWT.TAB key you lose focus on your current text box and don't gain focus on anything else...

Questions:

1.) Can each control only have one KeyListener?

2.) Why is the original TAB traversal not working anymore?

Thanks in advance!

A: 

Hi Martin,

to 1) I'm pretty sure that more than one KeyListener is allowed.

to 2) I'm not sure, that depends on what you're doing in your KeyAdapter. Maybe you can post that too?

I just the tab order is broken somehow, you can reset ( or change ) it with a call to setTabList( Control[] ).

setTablList( new Control[] {
    control1,
    control2,
    control3,
    ....
} );
derBiggi
A: 

So after more time learning and developing with SWT i've discovered my problem. When you add a listener it is applied to the widget/control you call the addXXXListener function on. So if that control is not active the listeners will not be fired.

The solution seems to be SWT's global Filter mechanism which allows you to add global application(Display) scope listeners.

Display.getCurrent().addFilter(SWT.keyPress, new KeyPressListener());

Pardon the incorrectness of this line, but if you google it you'll see what i mean.

I have also read to use this sparingly.

Martin Dale Lyness