画像ビューアーの制御をショートカットキーで実現しようと、Scene のインスタンスに onKeyPressed を使っていた。
順調に進んでいたけど、"+" で拡大処理を実装したところ、"+" だけ何も表示が変わらない。"-" は正しく縮小処理がされるのに…。
原因は、日本語キーボードでは "+" は "Shift + ; " で、onKeyPressed では "Shift" キーでイベント処理、 ";" キーで次のイベント処理になっていた。
KeyEvent (JavaFX 8) によると、onKeyTyped を使う必要がある。
以下のコードで、キーを押したときにそれぞれ何が呼び出されるかを調べることができる。
onKeyTyped を使うときは、getCharacter メソッドで入力された文字を文字列として解釈する必要がある。
逆に、shift や insert キーなど文字列にならないキーは onKeyPressed でしか検知できない。
package application; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.input.KeyEvent; import javafx.scene.layout.BorderPane; public class Main extends Application { @Override public void start(Stage primaryStage) { try { BorderPane root = new BorderPane(); Scene scene = new Scene(root,400,400); scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); // キーイベントを登録する scene.setOnKeyPressed(this::keyPressed); scene.setOnKeyTyped(this::keyTyped); scene.setOnKeyReleased(this::keyReleased); } catch(Exception e) { e.printStackTrace(); } } private void keyPressed(KeyEvent e) { System.out.println("Pressed:" + e.getCode().getName()); } private void keyTyped(KeyEvent e) { // KEY_TYPED イベントでは code フィールドと text フィールドは使用されない System.out.println("Typed (code): " + e.getCode().getName()); // KEY_TYPED イベントでは character フィールドが使用される System.out.println("Typed (char): " + e.getCharacter()); } private void keyReleased(KeyEvent e) { System.out.println("Released: " + e.getCode().getName()); } public static void main(String[] args) { launch(args); } }
以下は実行結果。
"a" キーを押した時。
Pressed:A Typed (code): Undefined Typed (char): a Released: A
"shift" + "a" つまり "A" を押した時。
Pressed:Shift Pressed:A Typed (code): Undefined Typed (char): A Released: A Released: Shift
"shift" + ";" つまり "+" を押した時(日本語キーボードの場合)。
Pressed:Shift Pressed:Semicolon Typed (code): Undefined Typed (char): + Released: Semicolon Released: Shift
"Delete" を押した時。onKeyTyped で検知できているけど、文字列はバイナリ値が表示された。(以下の結果は大文字の□で書き直している。)
Pressed:Delete Typed (code): Undefined Typed (char): □ Released: Delete
"Insert" を押した時。"shift" などと同様、onKeyTyped はイベントが発生していない。
Pressed:Insert Released: Insert