Как определить ctrl-f в моем приложении SWT

Я написал SWT-интерфейс, который имеет основную функцию отображения текста в элементе управления StyledText. Я хочу добавить обработчик для Ctrl + F, чтобы при нажатии этой клавиши фокус был установлен в поле поиска. Я попытался использовать следующий код для обнаружения нажатия клавиши.

sWindow = new Shell();
...
sWindow.getDisplay().addFilter(SWT.KeyDown, new Listener()
{
  @Override
  public void handleEvent(Event e)
  {
    System.out.println("Filter-ctrl: " + SWT.CTRL);
    System.out.println("Filter-mask: " + e.stateMask);
    System.out.println("Filter-char: " + e.character);
  }
});

Я ожидал, что когда я нажал Ctrl + F, я увижу следующий вывод:

Filter-ctrl: 262144
Filter-mask: 262144
Filter-char: f

Однако на практике я действительно вижу следующее.

Filter-ctrl: 262144
Filter-mask: 262144
Filter-char: <unprintable char - displayed as a box in eclipse console>

У меня есть два вопроса:

  • Является ли Display.addFilter(...) лучшим способом добавления глобального ярлыка? Я попробовал Display.addListener(...), но это вообще не получало никаких событий.
  • Почему я не получаю нажатый символ, когда я удерживаю Ctrl? Когда я удерживаю Alt или shift, я получаю ожидаемую маску и нажатый символ.

Ответ 1

Is Display.addFilter(...) the best way to add a glbal shortcut? I tried Display.addListener(...) but this didn't receive any events at all.

Да, обычно Display.addFilter(...) - лучший способ добавить ярлык, потому что у них более высокое предпочтение над прослушивателями событий. См. Следующий комментарий от Display.addFilter(...) javadoc.

Поскольку фильтры событий запускаются перед другими слушатели, фильтры событий могут заблокировать других слушателей и установить произвольные поля в событии. Для по этой причине фильтры событий мощный и опасный. Им следует как правило, следует избегать для выполнения, отладка и обслуживание кода причины.


Для вашего второго вопроса:

Why don't I get the pressed character when I'm holding down ctrl? When I hold down alt or shift I get the expected mask and the pressed character.

Проблема в том, что вы смотрите на неправильное место. Вместо запроса e.character вы должны использовать e.keyCode. В соответствии с javadoc e.character вы не получите только символ f:

В зависимости от события символ представленный ключом, который был напечатан. Это последний персонаж, который результаты после того, как все модификаторы были применяется. Например, когда пользователь типы Ctrl + A, значение символа равно 0x01 (ASCII SOH).

Итак, когда вы нажимаете CTRL + f, тогда он преобразуется в 0x06 (ASCII ACK). Это не тот случай, когда вы делаете ALT + f или SHIFT + f.

С другой стороны, javadoc e.keyCode говорит:

в зависимости от события, key codeключа, который был набран, как определено константами key code в классе SWT. Когда поле символов событие неоднозначно, это поле содержит незатронутое значение оригинальный знак. Например, набрав Ctrl + M или Введя оба результата в символ '\ r', но keyCode поле также будет содержать '\ r', когда Enter был введен и "m", когда Ctrl + M был напечатан.

Проверьте приведенный ниже код для получения более подробной информации. Для демонстрации я попытался поставить слушателя на Display и Test.

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class ControlF 
{
    public static void main(String[] args) 
    {

        Display display = new Display ();

        final Shell shell = new Shell (display);
        final Color green = display.getSystemColor (SWT.COLOR_GREEN);
        final Color orig = shell.getBackground();

        display.addFilter(SWT.KeyDown, new Listener() {

            public void handleEvent(Event e) {
                if(((e.stateMask & SWT.CTRL) == SWT.CTRL) && (e.keyCode == 'f'))
                {
                    System.out.println("From Display I am the Key down !!" + e.keyCode);
                }
            }
        });

        shell.addKeyListener(new KeyListener() {
            public void keyReleased(KeyEvent e) {
                if(((e.stateMask & SWT.CTRL) == SWT.CTRL) && (e.keyCode == 'f'))
                {
                    shell.setBackground(orig);
                    System.out.println("Key up !!");
                }
            }
            public void keyPressed(KeyEvent e) {
                if(((e.stateMask & SWT.CTRL) == SWT.CTRL) && (e.keyCode == 'f'))
                {
                    shell.setBackground(green);
                    System.out.println("Key down !!");
                }
            }
        });

        shell.setSize (200, 200);
        shell.open ();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();

    }
}