【问题标题】:java key-bindings - don't catch the CTRL of AltGr in windowsjava 键绑定 - 不要在 Windows 中捕捉 AltGr 的 CTRL
【发布时间】:2015-08-16 12:18:28
【问题描述】:

在 java 键绑定中,在 windows 中,如何识别何时按下 CTRL 键本身,而不是何时按下 AltGr?

我的进程处理必须由CTRL键自己启动,我还需要知道CTRL键什么时候松开。

瑞士/德国法语用户出现问题:要键入“@”,他们必须同时按“AltGr”+“2”。 在这种情况下,windows 将 AltGr 转换为 ALT + CTRL 并且我的进程启动错误。

我指出我想使用键绑定。

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class MyCtrl extends JFrame {

void init() {

    JPanel panel = new JPanel();
    setContentPane(panel);

    InputMap inputMap = panel.getInputMap();
    ActionMap actionMap = panel.getActionMap();

    /**
     * action for CTRL
     */
    KeyStroke controlKey = KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK);
    inputMap.put(controlKey, "ctrl");
    actionMap.put("ctrl", new CtrlAction());

    /**
     * action for release CTRL
     */
    KeyStroke releaseControlKey = KeyStroke.getKeyStroke("released CONTROL");
    inputMap.put(releaseControlKey, "release ctrl");
    actionMap.put("release ctrl", new ReleaseCtrlAction());
}

public class CtrlAction extends AbstractAction {

    @Override
    public void actionPerformed(ActionEvent e) {
        if(AltGr is pressed)
           {// do nothing}
        else
           System.out.println("control");
    }
}

public class ReleaseCtrlAction extends AbstractAction {

    @Override
    public void actionPerformed(ActionEvent e) {
        if(AltGr is pressed)
           {// do nothing}
        else
           System.out.println("release control");
    }
}

/**
 * main
 */
public static void main(String[] a) {
    MyCtrl myProjet = new MyCtrl();
    myProjet.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myProjet.setPreferredSize(new Dimension(200, 100));
    myProjet.init();
    myProjet.pack();
    myProjet.setVisible(true);
}

}

【问题讨论】:

    标签: java key-bindings ctrl


    【解决方案1】:

    我能想到两种解决方案:

    1. 不使用面板的输入/动作映射 - 在 KeyListener() 中处理操作。这似乎是一个直接的解决方案。

    2. 将 ALT 键处理添加到输入/操作映射并在处理程序中保留一个可以在控制处理程序中检查的标志。

    不过我更喜欢 (1)。

    【讨论】:

      【解决方案2】:

      感谢 KDM。正如我所解释的,我想使用键绑定,所以我首先尝试了你的第二个想法。但是按 AltGr 时,我无法捕捉到窗口启动的 ALT 修饰符。
      所以我选择了第一个解决方案,假设测试 ALT/CTRL 修饰符是一种特殊情况,使用键绑定不容易处理。
      另见here。 非常欢迎改进/建议。

      import java.awt.Dimension;
      import java.awt.KeyEventDispatcher;
      import java.awt.KeyboardFocusManager;
      import java.awt.event.KeyEvent;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      
      public class MyCtrl3 extends JFrame {
      
      private class MyDispatcher implements KeyEventDispatcher {
          // usualy one prefer using keybindings - but we are in
          // special case for detect AltGr
          @Override
          public boolean dispatchKeyEvent(KeyEvent e) {
              if (e.getID() == KeyEvent.KEY_PRESSED) {
                  if (e.isAltGraphDown()) {
                      // uncaught in windows
                      System.out.println("ALT GRAPH");
                  } else if (e.isControlDown()) {
                      // fired 1 by windows when press AltGr
                      System.out.println("CONTROL");
                      // here I launch a timer, 1ms delay is enough 
                      // to wait for ALT key if coming
                  } else if (e.isAltDown()) {
                      // fired 2 by windows when press AltGr
                      // here I unarm the timer
                      System.out.println("ALT");
                  }
              } else if (e.getID() == KeyEvent.KEY_RELEASED) {
                  if (e.getKeyCode() == KeyEvent.VK_ALT_GRAPH) {
                      System.out.println("ALT GRAPH released");
                  } else if (e.getKeyCode() == KeyEvent.VK_ALT) {
                      System.out.println("ALT released");
                  } else if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
                      System.out.println("CONTROL released");
                  }
              }
              return false;
          }
      }
      
      public MyCtrl3() {
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setPreferredSize(new Dimension(200, 100));
          KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
          manager.addKeyEventDispatcher(new MyDispatcher());
      }
      
      public static void main(String[] a) {
          MyCtrl3 myProjet = new MyCtrl3();
          myProjet.pack();
          myProjet.setVisible(true);
      }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 2011-07-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多