按鍵事件 (Key Event) 是當使用者按下或放開鍵盤按鍵時所產生的事件,除了A~Z與0~9等按鍵之外,最常處理的按鍵包括上下左右鍵、Page Up、Page Down、Alt、Shift、Ctrl等特殊功能鍵。
按鍵事件包括按下鍵盤按鍵 (Pressed)、放開鍵盤按鍵 (Released) 與按下並放開鍵盤按鍵 (Typed) 等三種,前兩者為低階 (Low-Level) 並與作業平台及鍵盤配置有關的事件,後者則是高階 (High-Level) 並與作業平台及鍵盤配置無關的事件。
JavaFX按鍵事件的類別為KeyEvent,繼承自InputEvent類別,按鍵事件為Node抽象類別與Scene類別所定義之事件,因此凡繼承Node抽象類別的物件,均會產生按鍵事件。
按鍵事件可分別以setOnKeyPressed()、setOnKeyReleased()與setOnKeyTyped()方法設定按下鍵盤按鍵、放開鍵盤按鍵與按下並放開鍵盤按鍵的Event Handler函式。
KeyEvent類別定義以下的事件類型,以做為註冊Event Handler與Event Filter之用:
- KeyEvent.KEY_PRESSED:按下鍵盤按鍵。
- KeyEvent.KEY_RELEASED:放開鍵盤按鍵。
- KeyEvent.KEY_TYPED:按下並放開鍵盤按鍵。
- KeyEvent.ANY:代表上述任一種事件類型。
以setOnKeyPressed()設定為例,分別以isAltDown()、isControlDown()與isShiftDown()方法判斷是否按下Alt鍵、Ctrl鍵與Shift鍵,此外並以getCode()方法取得按鍵值,判斷是否按下上下左右鍵、上一頁與下一頁按鍵,藉此移動視窗:
// Key Pressed scene.setOnKeyPressed(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent e) { int dx = 0; int dy = 0; // 判斷是否按下Alt鍵 if (e.isAltDown()) label.setText("Press Alt key") ; // 判斷是否按下Ctrl鍵 if (e.isControlDown()) label.setText("Press Control key") ; // 判斷是否按下Shift鍵 if (e.isShiftDown()) label.setText("Press Shift key") ; label.setText("Press " + e.getCode().getName()) ; // 取得按鍵按鍵值,判斷是否按下上下左右鍵、上一頁與下一頁按鍵 if (e.getCode() == KeyCode.UP) dy = -5; else if (e.getCode() == KeyCode.DOWN) dy = 5; else if (e.getCode() == KeyCode.LEFT) dx = -5; else if (e.getCode() == KeyCode.RIGHT) dx = 5; else if (e.getCode() == KeyCode.PAGE_UP) dy = -100; else if (e.getCode() == KeyCode.PAGE_DOWN) dy = 100; stage.setX(stage.getX() + dx); stage.setY(stage.getY() + dy); } }); |
除了上述語法之外,亦可以建立類別的方式處理,請參考以下範例:
// Key Pressed scene.setOnKeyPressed(onKeyPressedEventHandler); ... EventHandler onKeyPressedEventHandler = new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent e) { int dx = 0; int dy = 0; // 判斷是否按下Alt鍵 if (e.isAltDown()) label.setText("Press Alt key") ; // 判斷是否按下Ctrl鍵 if (e.isControlDown()) label.setText("Press Control key") ; // 判斷是否按下Shift鍵 if (e.isShiftDown()) label.setText("Press Shift key") ; label.setText("Press " + e.getCode().getName()) ; // 取得按鍵按鍵值,判斷是否按下上下左右鍵、上一頁與下一頁按鍵 if (e.getCode() == KeyCode.UP) dy = -5; else if (e.getCode() == KeyCode.DOWN) dy = 5; else if (e.getCode() == KeyCode.LEFT) dx = -5; else if (e.getCode() == KeyCode.RIGHT) dx = 5; else if (e.getCode() == KeyCode.PAGE_UP) dy = -100; else if (e.getCode() == KeyCode.PAGE_DOWN) dy = 100; stage.setX(stage.getX() + dx); stage.setY(stage.getY() + dy); } }; |
第二種方式是以addEventHandler()方法註冊事件的Event Handler,請參考以下範例,以按下鍵盤按鍵事件為例,其程式如下:
// Key Pressed scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent e) { int dx = 0; int dy = 0; // 判斷是否按下Alt鍵 if (e.isAltDown()) label.setText("Press Alt key") ; // 判斷是否按下Ctrl鍵 if (e.isControlDown()) label.setText("Press Control key") ; // 判斷是否按下Shift鍵 if (e.isShiftDown()) label.setText("Press Shift key") ; label.setText("Press " + e.getCode().getName()) ; // 取得按鍵按鍵值,判斷是否按下上下左右鍵、上一頁與下一頁按鍵 if (e.getCode() == KeyCode.UP) dy = -5; else if (e.getCode() == KeyCode.DOWN) dy = 5; else if (e.getCode() == KeyCode.LEFT) dx = -5; else if (e.getCode() == KeyCode.RIGHT) dx = 5; else if (e.getCode() == KeyCode.PAGE_UP) dy = -100; else if (e.getCode() == KeyCode.PAGE_DOWN) dy = 100; stage.setX(stage.getX() + dx); stage.setY(stage.getY() + dy); } }); |
第三種方式是以addEventFilter()方法註冊事件的Event Filter,請參考以下範例,幾乎與上述範例一樣:
// Key Pressed scene.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent e) { int dx = 0; int dy = 0; // 判斷是否按下Alt鍵 if (e.isAltDown()) label.setText("Press Alt key") ; // 判斷是否按下Ctrl鍵 if (e.isControlDown()) label.setText("Press Control key") ; // 判斷是否按下Shift鍵 if (e.isShiftDown()) label.setText("Press Shift key") ; label.setText("Press " + e.getCode().getName()) ; // 取得按鍵按鍵值,判斷是否按下上下左右鍵、上一頁與下一頁按鍵 if (e.getCode() == KeyCode.UP) dy = -5; else if (e.getCode() == KeyCode.DOWN) dy = 5; else if (e.getCode() == KeyCode.LEFT) dx = -5; else if (e.getCode() == KeyCode.RIGHT) dx = 5; else if (e.getCode() == KeyCode.PAGE_UP) dy = -100; else if (e.getCode() == KeyCode.PAGE_DOWN) dy = 100; stage.setX(stage.getX() + dx); stage.setY(stage.getY() + dy); } }); |
【參考資料】
[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,深入研究Java Swing。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 2.2 API Specification.
[6] Java Platform, Standard Edition 7 API Specification.
© Chia-Hui Huang
沒有留言:
張貼留言