Java SWT изменить типизированный символ - PullRequest
2 голосов
/ 13 августа 2011

У меня есть виджет браузера SWT, в котором пользователь может печатать с клавиатуры, мне нужно, чтобы один пользователь нажимал на него другим.например, когда пользователь нажимает x, я меняю его y.

Я добавляю ключевой слушатель, где я могу заблокировать ввод пользователя с помощью doit = ​​false;но теперь я не могу передать свой характер.

вот что я делаю:

    browser_1.addListener(SWT.KeyDown, new Listener() {


    public void handleEvent(Event arg0) {           

        if(arg0.character=='x')
        {
            arg0.doit=false;
            //now here how to send y as a charachter to browser widget
        }
        }
});

Другими словами, могу ли я каким-то образом изменить символ на другой, не используя arg0.doit = ​​false;

Ответы [ 3 ]

4 голосов
/ 13 августа 2011

Итак, после некоторого поиска, вот решение

В SWT вы можете добавить к экрану экземпляр слушателя 'filter', который может изменять практически все в событии (см. документы для подробностей ).

Предупреждение от Javadoc: Установка типа события для SWT. Ни один из метода handleEvent () не может использоваться для изменения типа события и остановки запуска последующих прослушивателей Java. Поскольку фильтры событий выполняются перед другими прослушивателями, фильтры могут блокировать других прослушивателей и устанавливать произвольные поля в событии. По этой причине фильтры событий являются мощными и опасными. Как правило, их следует избегать по причинам производительности, отладки и обслуживания кода.

Вот код (меняет любой набранный ключ на символ 'l' и пишет это в консоли, когда событие действительно возникает)

browser.addListener(SWT.KeyDown, new Listener() {
    public void handleEvent(Event event) {
        System.out.println(event.character);
    }
});

display.addFilter(SWT.KeyDown, new Listener() {
    public void handleEvent(Event event) {
        if(event.widget instanceof Browser) {
            event.character = 'l';
        }
    }
});

ИМХО, это действительно грязное решение, реализация на стороне браузера (на JavaScript) намного красивее

Также, когда я смотрю на ваш код (во всяком случае, я не знаю, просто ли это какое-то тестирование, проверочный код), использование переменных с something_number или arg0 меня огорчает. Это делает код таким нечитаемым и неясным, старайтесь избегать его;] ..

2 голосов
/ 08 ноября 2011

Вы можете сделать следующее:

Text textControl = new Text(...);
textControl.addKeyListener(this);
...
public void keyPressed(KeyEvent e) {
   if (e.character == 'x' && (e.stateMask & SWT.CONTROL) == 0) {
       e.doit = false;
       textControl.insert("y");
   }
}

Некоторые комментарии к этому коду:

  1. Мы проверяем e.stateMask, потому что нам все еще нужно сохранить CTRL + X в качестве функции вырезания. Обратите внимание, если вы используете вместо текущего кода этот (который просто проверяет, что никакая специальная кнопка не нажата):

    if (e.character == 'x' && e.stateMask == 0)

    Вы получите ошибку, когда CapsLock включен. В этом случае пользователь должен нажать Shift + X, чтобы уменьшить x.

  2. Метод insert ("y") вставляет символ в место курсора. Когда выделен какой-либо текст, весь выбор будет заменен на «y».

  3. В текущем примере изменяется только нижний регистр "x". Вы должны изменить его, если необходимо обработать, также измените верхний X на Y.

0 голосов
/ 26 сентября 2014

У меня было похожее требование: преобразование десятичного разделителя нажмите на клавиатуре (точка) в десятичный разделитель нашего языка (запятая).Я попробовал ту же идею, что и Sorceror, но у меня она тоже не сработала.Что работает, так это установка event.doit = ​​false и публикация нового события, которое является клоном исходного события с заменой символа:

@Override
public void handleEvent(Event event) {
    if (event.widget instanceof Browser && event.character == 'x') {
        Event eventClone = cloneEvent(event);
        eventClone.character = 'y'; 
        event.doit = false;
        display.post(eventClone);
    }
}

(Если display - локальная переменная, вам нужно сделать ее окончательной.) Я создал небольшой служебный метод для создания клона события:

/**
 * @return a clone of the given {@link Event}
 */
public static Event cloneEvent(Event event) {
    Event clone = new Event();
    clone.display = event.display;
    clone.widget = event.widget;
    clone.type = event.type;
    clone.detail = event.detail;
    clone.item = event.item;
    clone.index = event.index;
    clone.gc = event.gc;
    clone.x = event.x;
    clone.y = event.y;
    clone.width = event.width;
    clone.height = event.height;
    clone.count = event.count;
    clone.time = event.time;
    clone.button = event.button;
    clone.character = event.character;
    clone.keyCode = event.keyCode;
    clone.keyLocation = event.keyLocation;
    clone.stateMask = event.stateMask;
    clone.start = event.start;
    clone.end = event.end;
    clone.text = event.text;
    clone.doit = event.doit;
    clone.data = event.data;
    clone.touches = event.touches;
    clone.xDirection = event.xDirection;
    clone.yDirection = event.yDirection;
    clone.magnification = event.magnification;
    clone.rotation = event.rotation;
    return clone;
}
...