且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在我的 SWT 应用程序中检测 ctrl-f

更新时间:2022-11-18 10:47:59

Display.addFilter(...) 是添加全局快捷方式的***方式吗?我试过 Display.addListener(...) 但这根本没有收到任何事件.

是的,通常 Display.addFilter(...) 是添加 glbal 快捷方式的***方式,因为它们比事件侦听器具有更高的偏好.请参阅 Display.addFilter(...) javadoc 中的以下注释.

Yes, normally Display.addFilter(...) is the best way to add a glbal shortcut because they have higher preference over the event listeners. See the below comment from Display.addFilter(...) javadoc.

因为事件过滤器在其他过滤器之前运行监听器,事件过滤器都可以阻止其他侦听器并设置事件中的任意字段.为了因此,事件过滤器都是强大而危险.他们应该通常为了性能而避免,调试和代码维护原因.

Because event filters run before other listeners, event filters can both block other listeners and set arbitrary fields within an event. For this reason, event filters are both powerful and dangerous. They should generally be avoided for performance, debugging and code maintenance reasons.

第二个问题:

为什么我在按住 ctrl 时没有得到按下的字符?当我按住 alt 或 shift 时,我得到了预期的掩码和按下的字符.

问题是你看错了地方.您应该使用 e.keyCode 而不是查询 e.character.根据 e.character 的 javadoc,您不会只得到字符 f:

The problem is that you are looking at the wrong place. Instead of querying e.character you should be using e.keyCode. As per javadoc of e.character you won't get just character f:

根据事件,角色由键入的键表示.这是最后一个角色所有修饰符后的结果应用.例如,当用户键入Ctrl+A,字符值为0x01 (ASCII SOH).

Depending on the event, the character represented by the key that was typed. This is the final character that results after all modifiers have been applied. For example, when the user types Ctrl+A, the character value is 0x01 (ASCII SOH).

因此,当您按下 CTRL+f 时,它会转换为 0x06(ASCII ACK).当您执行 ALT+f SHIFT+f 时,情况并非如此.

So when you press CTRL+f then it converts in 0x06 (ASCII ACK). Which is not the case when you do ALT+f or SHIFT+f.

另一方面,e.keyCode 的 javadoc 说:

On the other hand the javadoc of e.keyCode says:

根据事件,关键代码键入的键,如定义的那样通过类中的关键代码常量SWT.当字符字段事件不明确,这个字段包含不受影响的值原始字符.例如,键入 Ctrl+M 或 Enter both 结果字符 ' ' 但 keyCode字段也将包含 ' ' 时当 Ctrl+M 时输入了 Enter 和 'm'已输入.

depending on the event, the key code of the key that was typed, as defined by the key code constants in class SWT. When the character field of the event is ambiguous, this field contains the unaffected value of the original character. For example, typing Ctrl+M or Enter both result in the character ' ' but the keyCode field will also contain ' ' when Enter was typed and 'm' when Ctrl+M was typed.

查看以下代码了解更多详情.对于演示,我尝试将侦听器放在 DisplayTest 上.

Check the below code for more details. For demo I have tried to put listener on Display and 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 ();

    }
}