【问题标题】:Why does KeyStroke.getKeyStroke('s', KeyEvent.ALT_MASK) create an Alt-F4 keybinding?为什么 KeyStroke.getKeyStroke('s', KeyEvent.ALT_MASK) 创建 Alt-F4 键绑定?
【发布时间】:2017-05-03 19:50:49
【问题描述】:

运行以下:

    KeyStroke ks1 = KeyStroke.getKeyStroke('s', KeyEvent.ALT_MASK);
    KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.ALT_MASK);
    KeyStroke ks3 = KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.ALT_MASK);

    System.out.println(ks1);
    System.out.println(ks2);
    System.out.println(ks3);

结果:

    alt pressed F4
    alt pressed S
    alt pressed F4

【问题讨论】:

    标签: java keylistener key-bindings windowlistener


    【解决方案1】:

    这是因为:

    • char 's' 的 int 值为 115
    • KeyEvent.VK_F4的int值也是 115

    意味着k1k3 在功能上是相同的。

    【讨论】:

      【解决方案2】:

      没有方法 getKeyStroke(char, int),因此编译器将您的 char 's' 扩展为 int 并调用 getKeyStroke(int, int)。后者需要一个虚拟键码,而不是 unicode 字符。

      由于 (int) 's' 扩大到与 VK_F4 重合的 int 115,它完全按照您告诉它的操作:使用 VK_F4 创建一个键绑定并屏蔽 ALT。

      基本上发生的事情是,您想要为 char 's' 创建一个键绑定,但编译器选择为 int 115 创建一个键绑定。这是一个简单的错误,即假设重载不会存在,但一个兼容的、语义不同的重载被编译器替换。

      【讨论】:

      • 问题的一个方面是大写字母 A-Z 的 VK 值与它们的 char/int 值匹配,因此对于这些字符来说问题是隐藏的。 IE。使用大写的“S”可以正常工作,而小写的“s”则不行。
      • @BenCole 我不会称其为“方面”,它仍在调用 getKeyStroke(int, int)。只有值确实符合预期。我仍然会认为以这种方式使用 getKeyStroke() 的代码是错误的。它不比即 JScrollPane.setHorizo​​ntalScrollBarPolicy(' '); 更正确这也碰巧像 HORIZONTAL_SCROLLBAR_​​ALWAYS 一样起作用。
      • 只要使用大写字符,代码似乎“正常工作”,尽管如您所说,有问题。这是不正确的,不,但它确实有效,尤其是在 IDE 中,人们可能不会注意到 getKeyStroke(char, int) 不存在。
      • @BenCole 是的,我完全同意,很容易在不知不觉中犯错误,并且未被发现的可能性很高。但是您要提出的特殊论点是什么?如果你明白这一点,它可以设计得更好、更安全,是的,当然它可以设计得更好。但它就是它本来的样子,并且为了保持兼容性将保持不变。
      • -- 我根本不想争论!我想把它添加到 StackOverflow,因为我遇到了它,但找不到任何关于它的信息。
      猜你喜欢
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多