SWT Global KeyListener Button Focus Problem

2019-02-18 15:01发布

问题:

for my app I need the space key to call a function independent from the focused widget, everywhere in the app but only if the according tab is opend. I found that one can add a filter to the display, like this:

 getShell().getDisplay().addFilter(SWT.KeyDown, new Listener() {

            public void handleEvent(Event arg0) {
                if( arg0.character == 32 ) { /**SPACE*/
                    if( mainTabs.getSelection().equals(analyseSoundFilesTab)) {
                        soundController.playButtonClickHandler();
                    }
                }
            }

        });

That works fine most of the time, but if I give a button the focus via the "tab" or "shift tab", its kinda strange - the space bar will than activate a "button pressed", as if one clicks the button with the mouse. Im a bit stuck now, I don't know how to avoid this... For the buttons, I have implemented a SelectionListener.

Regards.

回答1:

You can use TraverseListener and disabled press event detection using doin field. Here is a sample code:

display.addFilter(SWT.KeyDown, new Listener() {
    public void handleEvent(Event e) {
        if (e.character == 32) {
            System.out.printf("Space detected %s\n", e);
        }
    }
});

Button b1 = new Button(shell, SWT.PUSH);
b1.addSelectionListener(new SelectionAdapter() {
    @Override
    public void widgetSelected(SelectionEvent se) {
        System.out.printf("Button pressed %s\n", se);
    }
});

b1.addTraverseListener(new TraverseListener() {
    @Override
    public void keyTraversed(TraverseEvent te) {
        System.out.printf("Traverse detected %s\n", te);
        te.doit = true;
    }
});

If addTraverseListener() didn't exist, your space button was detected after filter, so you would see "Space detected..." and after that "Button pressed...". Now that you set te.doit = true, you say to SWT to do space bar traversal (which does nothing actually) instead of firing key listener. You may optionally check te.detail to only prevent mnemonic traversals.



回答2:

Choosing the 'Space key' is the real problem, because it is a general feature in most (all?) OS's that pressing space is equal to selecting the widget that has focus.

A way out would be using subclassed Button widgets that ignoring Space.

But it would confuse a lot of users, just because they expect that a focussed button is selected when they hit space and do not expect some other action.



标签: java swt