如何使用 KeyAdapter 检测 CTRL+SHIFT+ANY_KEY?

How can I detect CTRL+SHIFT+ANY_KEY using a KeyAdapter?

这是我的代码:

        tabbedPane.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {

                CheckShortcut controlShortcut = (key) -> {
                    return (evt.getKeyCode() == key) && ((evt.getModifiers() & KeyEvent.CTRL_MASK) != 0);
                };

                CheckShortcut controlShiftShortcut = (key) -> {
                    return (evt.getKeyCode() == key) && ((evt.getModifiers() & KeyEvent.CTRL_MASK & KeyEvent.SHIFT_MASK) != 0);
                }; // Does not work <<<<<

                if (controlShortcut.f(KeyEvent.VK_N)) {
                    createNewFile();
                } else if (controlShortcut.f(KeyEvent.VK_O)) {
                    openFile();
                } else if (controlShortcut.f(KeyEvent.VK_S)) {
                    save();
                } else if (controlShiftShortcut.f(KeyEvent.VK_S)) {
                    saveAs();
                } else if (controlShortcut.f(KeyEvent.VK_Q)) {
                    System.exit(0);
                } else if (controlShortcut.f(KeyEvent.VK_W)) {
                    MainFrame.toggleFrame(qrWebcamFrame);
                } else if (controlShortcut.f(KeyEvent.VK_C)) {
                    MainFrame.toggleFrame(comandaCreationFrame);
                } else if (controlShortcut.f(KeyEvent.VK_P)) {
                    if (accessPasswordFrame("Senha de administrador",
                            "Login: ", "Senha de administrador inválida.",
                            ADMIN_TYPE)) {
                        MainFrame.toggleFrame(passwordFrame);
                    }
                }

            }   
        });

controlShortcut 完美运行。然而,当我将 KeyEvent.SHIFT_MASK 添加到测试中时,它不起作用。另外,当我这样做时:

        CheckShortcut controlShiftShortcut = (key) -> {
            return (evt.getKeyCode() == key) && ((evt.getModifiers() & KeyEvent.CTRL_MASK) != 0) && ((evt.getModifiers() & KeyEvent.SHIFT_MASK) != 0);
        };

它也不行。我不明白为什么,因为我只是添加相同的测试。

你在口罩上用错了bitwise-operator。
JavaDocs

正确的方法应该是:

int mask = CTRL_DOWN_MASK | SHIFT_DOWN_MASK;
if(evt.getModifiersEx() & mask == mask) {doStuff();}  

另请参阅以下方法:

evt.isControlDown();
evt.isAltDown();
evt.isShiftDown();

您可以只为 shift 和 control 创建两个布尔值。

public class DummyClass implements KeyListener{
    boolean shift = false, control = false;

    public void KeyPressed(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_SHIFT)
        {
            shift = true;
        }        
        if(e.getKeyCode() == KeyEvent.VK_CONTROL)
        {
            control = true;
        }
        if(shift && control)
        { 
            //Do something 
        }
        else if(shift)
        { 
            //Do something
        }
        else if(control)
        { 
            //Do something 
        }
    }
    public void KeyReleased(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_SHIFT)
        {
            shift = false;
        }        
        if(e.getKeyCode() == KeyEvent.VK_CONTROL)
        {
            control = false;
        }
    }
}

这不是按位运算符的工作方式。 KeyEvent.CTRL_MASK & KeyEvent.SHIFT_MASK 总是给出 0 因为你是 AND-ing 不同的面具。

您要做的是使用 OR 为两者创建一个掩码:

int down = KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK;
if ((e.getModifiersEx() & down) == down && (e.getKeyCode() == KeyEvent.VK_D))
    System.out.println(true);

这将打印

true

仅当按下ctrl+shift+D时。

如果你写

(e.getModifiersEx() & down) != 0

它将检查 ctrlshift 中的 any(或两者)是否被按下.

请注意,您应该将 getModifiersExX_DOWN_MASK 一起使用,而不是将 getModifiersX_MASK 一起使用。