Как обнаружить Ctrl-F в моем приложении SWT - PullRequest
10 голосов
/ 30 апреля 2011

Я написал пользовательский интерфейс 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 Ответ

31 голосов
/ 30 апреля 2011

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 говорит:

в зависимости от события, код клавиши, который был набран, как определено константами кода клавиши вкласс SWT.Когда символьное поле события неоднозначно, это поле содержит неизмененное значение исходного символа.Например, нажатие клавиш Ctrl + M или Enter приводит к появлению символа «\ 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 ();

    }
}
...