1

I have a SWT GUI, containing different elements (Text, Buttons, Labels...) which are themselves in different Composites.

I would like to make the navigation easier using some keybindings such as "Alt+c" to call the Cancel Button, "Alt+f" to call the finish button etc... When using a KeyListener on a specific component, the listener is triggered, but it implies that the component has the focus (and this is not very convenient !).

So I tried to register the listener on the shell itself, but the result is the same and nothing is triggered.

How should I proceed in order to get my listener triggered no matters what element is currently focused ?

Any hint would be appreciated. Thanks for reading.

Edit

Regarding the comments, I tried to add the keylistener recursively to all the composites of the GUI, and it's working. However, I guess there is probably a "clever" way to do it.

Community
  • 1
  • 1
MedAl
  • 457
  • 3
  • 19
  • 1
    The reason why your key event listeners aren't called is described here: http://stackoverflow.com/questions/7225756/swt-event-propagation – Rüdiger Herrmann Jun 03 '16 at 09:56
  • I was thinking to something similar at first, but I thought it would be too messy. I guess this is what I will try – MedAl Jun 03 '16 at 12:31

2 Answers2

2

You can use the Display addFilter or addListener methods to add a listener which is always called.

Display.getDefault().addListener(SWT.KeyDown, new Listener() {
  @Override
  public void handleEvent(final Event event) {
    // TODO handle event
  }
});

These listeners use the lower level Listener interface rather than KeyListener.

addFilter is similar to addListener but is called earlier and can change the event.

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • Unfortunately, it doesn't seem to work in my case. The event is still not caught ... Should I precise that the swt window is generated by a plugin in Eclipse ? – MedAl Jun 03 '16 at 12:31
  • If this is an Eclipse plugin you should say so as that is substantially different. You should look at the `org.eclipse.ui.bindings` extension point. But it depends a lot on exactly where these controls are. You need to show us code. – greg-449 Jun 03 '16 at 12:47
  • Sorry for the lack of precision. I will have a look to that extension – MedAl Jun 03 '16 at 12:49
0

The easiest way is to add a event filter to the display:

Here is an example I use to activate a search field when a user types command-F in our main application window.

    Display.getCurrent().addFilter(SWT.KeyDown, event -> {

        // Only respond to key events for our shell.
        if (getShell().equals(Display.getCurrent().getActiveShell())) {
            // Activate the focus for our search widget when user types 'f'
            // (control-f, command-f, or just f)
            if (event.keyCode == 'f') {
                if (!searchField.isFocusControl()) {
                    searchField.setFocus();
                }
            }
        }
    });
bhlowe
  • 418
  • 4
  • 8