如果我按如下所示设置KeyEvent
处理程序,则行为如我所料,并且正如Oracle文档似乎指定的那样,对于大写字母和非字母或数字的Ascii字符。
但是,对于小写字母,如果我在键入字母时按住Ctrl键,则EventHandler
似乎无法注册按键。
下面的输出显示了这一点,输入Q,q,$,Ctrl + Q,Ctrl + q,Ctrl + $。
任何人都可以阐明这种行为吗?我错过了什么吗?我搜索过但没有找到任何其他对此问题的引用。
import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.event.*;
import javafx.scene.input.KeyEvent;
// Test handling keypresses of upper and lower case letter, and non-alphameric ascii symbol,
// to see if any difference exists when Ctrl is held down
// between the handling for (ev.isShortcutDown()) and (ev.isMetaDown() || ev.isControlDown())
// and between the three character types
// Program to be tested by typing, in sequence,
// Q q $ Ctrl+Q Ctrl+q Ctrl+$
public class TestHandlingKeyEvents extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) throws Exception {
Scene scene = new Scene(new Group());
stage.setScene(scene);
EventHandler<KeyEvent> handleUserTyping = ev -> {
String charTyped = ev.getCharacter();
switch (charTyped) {
case "Q": // quit
System.out.println("\nQ typed ");
if (ev.isShortcutDown())
System.out.println("with Shortcut down ");
if (ev.isMetaDown() || ev.isControlDown())
System.out.println("with Meta or Ctrl down ");
break;
case "q": // complete reset
System.out.println("\nq typed ");
if (ev.isShortcutDown())
System.out.println("with Shortcut down ");
if (ev.isMetaDown() || ev.isControlDown())
System.out.println("with Meta or Ctrl down ");
break;
case "$": // back to last view
System.out.println("\n$ typed ");
if (ev.isShortcutDown())
System.out.println("with Shortcut down ");
if (ev.isMetaDown() || ev.isControlDown())
System.out.println("with Meta or Ctrl down ");
break;
}
};
scene.setOnKeyTyped(handleUserTyping);
stage.show();
}
}
输出:
john@jlaptop2:/java$ java TestHandlingKeyEvents
Q typed
q typed
$ typed
Q typed
with Shortcut down
with Meta or Ctrl down
$ typed
with Shortcut down
with Meta or Ctrl down
john@jlaptop2:/java$
答案 0 :(得分:1)
您使用了错误类型的事件来获得您想要的行为。
阅读KeyEvent javadoc中的各种类型的KeyEvent。
基本上,您可以在KEY_PRESSED事件而不是KEY_TYPED事件上注册事件处理程序。只有在底层系统注册通过键入生成的unicode字符时才会生成键类型事件,而对于您尝试捕获的某些键输入序列则不是这种情况。为了捕获更多与unicode字符生成无关的输入字符序列,需要使用较低级别的KEY_PRESSED(或KEY_RELEASED)事件。
但是,您可以使用更高级别的界面,并且可能更适合您的用例,即根据KeyCodeCombinations设置加速器。
使用加速器的示例
import javafx.application.Application;
import javafx.collections.ObservableMap;
import javafx.scene.*;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
// Test handling keypresses of upper and lower case letter,
// and non-alphameric ascii symbol.
// Program to be tested by typing, in sequence,
// Ctrl+Q Ctrl+q Ctrl+$
public class TestHandlingKeyAccelerators extends Application {
public void start(Stage stage) throws Exception {
Scene scene = new Scene(new Group());
stage.setScene(scene);
ObservableMap<KeyCombination, Runnable> accelerators =
scene.getAccelerators();
accelerators.put(
KeyCombination.valueOf("Ctrl+Q"),
() -> System.out.println("Ctrl+q -> reset")
);
accelerators.put(
KeyCombination.valueOf("Ctrl+Shift+Q"),
() -> System.out.println("Ctrl+Q -> quit")
);
accelerators.put(
KeyCombination.valueOf("Ctrl+Shift+'4'"),
() -> System.out.println("Ctrl+$ -> back to last view")
);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
注意KeyCombination.valueO f方法如何用于构造组合键。另请注意(每个键标识一个字符的除外)每个键都由其键码标识。因为,在我的键盘上,小写q和大写Q是相同的键,但是使用shift来生成大写键,然后Ctrl + q编码为Ctrl + Q,Ctrl + Q编码为Ctrl + Shift + Q.此外,我的键盘没有美元键,而是通过按shift和四键生成一美元。通常四个关键代码是DIGIT4,但由于某种原因,在这种情况下这不起作用。因此,为了获得Ctrl + $操作,我使用Ctrl + Shift +&#39; 4&#39;表示控制和移位修饰符,用于生成字符“4”的键。被压了。
评论原始样本的操作
此外,作为一个主要是琐事的旁注,在Mac(2012 MacBook Air OS X 10.11.4,Java 8u60)上进行测试时,您的程序会提供不同的输出,可能是由于不同的键盘系统或操作系统处理关键事件。 Mac上输出的建议密钥序列为:
Q typed
q typed
$ typed
您在问题中显示的以下输出序列不会在Mac上生成:
Q typed
with Shortcut down
with Meta or Ctrl down
$ typed
with Shortcut down
with Meta or Ctrl down