在java Swing編程過程中,經常需要處理鍵盤事件,例如處理快速鍵等。這裡就介紹如何定義鍵盤事件,以及如何處理這些事件。
在jdk1.2中,分別針對Jcomponent和Text類的對象定製了不同的處理鍵盤事件的方法:在Jcomponent中,定義了registerKeyboardAction方法,使用這個方法來將需要處理的鍵盤事件以及處理事件的行為綁定在一起。Text類中具有keymap對象,同Jcomponent中的處理方法類似,這個對象儲存著需要處理的鍵盤事件和對應的行為。
而在jdk1.3中,使用一種新的方法來處理鍵盤事件,它將jdk1.2的兩種方法整合在一起。不需要區分被處理的是Jcomponent還是Text類型的組件。它定義了兩個新的類:InputMap和ActionMap。他們均是簡單的表或映射。一個InputMap將一個Keystroke對應到一個對象,ActionMap將一個對象對應到一個行為(Action)。通常InputMap中KeyStroke所對應的對象是一個字串,通過這個字串可以在ActionMap中尋找到相應的行為。
InputMap和ActionMap中均有put方法。InputMap的put方法可以將Keystroke對應到一個對象,而ActionMap的put方法可以將一個對象對應到一個行為。
在每一個Jcomponent組件中,會有三個預設的InputMap和一個預設的ActionMap。他們可以通過調用getInputMap(int condition)和getActionMap()得到。三個InputMap分別是當組件本身擁有焦點時的InputMap(WHEN_FOCUSED),當組件的祖先擁有焦點時的InputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)和組件所在的表單具有焦點時的InputMap(WHEN_IN_FOCUSED_WINDOW)(括弧內表示為了得到這些InputMap,應該在getInputMap中設定的參數)。以下分別說明這三種InputMap:
1, 組件本身擁有焦點時的InputMap:當組件擁有焦點時,鍵盤按鍵按下,則java在這個InputMap中尋找鍵盤事件所對應的KeyStroke對象。
2, 組件的祖先擁有焦點時的InputMap:當組件的祖先擁有焦點時,鍵盤按鍵按下,則java尋找這個InputMap。
3, 組件所在的視窗擁有焦點時的InputMap:當組件所在的視窗具有焦點時,鍵盤按鍵按下,則java尋找這個InputMap。
當一個鍵被按下,這個事件被轉化成一個KeyStroke對象,java會尋找這個Jcomponent的相應InputMap(例如,當組件的祖先具有焦點時,java就尋找這個Jcomponent的祖先擁有焦點的InputMap)中是否有這個KeyStroke,如果有,取出它所對應的對象(通常是字串),利用這個對象在這個Jcomponent的ActionMap中尋找,如果找到對應的行為(Action),則java執行這個行為的actionPerformed方法(隨後介紹這個方法)。從而達到處理鍵盤事件的目的。
每一個InputMap可以具有parent屬性,這個屬性的值是一個InputMap。當在一個InputMap中尋找不到鍵盤事件的KeyStroke時,java會自動在它的parent屬性指定的InputMap中尋找,依次向上尋找,直至找到。使用parent的好處是:當有一些固定的,不希望使用者進行改動的鍵盤對應可以存放在parent屬性所指定的InputMap中,從而避免被意外修改;另外可以將多個Jcomponent的預設InputMap設定具有相同的parent,使得可以共用一些鍵盤綁定的設定。可以通過InputMap類的setparent()方法設定它的parent屬性。ActionMap也具有相同的parent屬性,使用方法也相同。
以上是如何將一個鍵盤事件對應到一個行為,以下就簡單介紹行為(Action)。
行為是一個實現了Action介面的類。在Action介面中定義了7個方法。其中最關鍵的是actionPerformed()方法。這個方法描述了這個行為的具體操作過程。其他幾個方法包括setEnabled,isEnabled,putValue,getValue,addPropertyChangeListener,和removePropertyChangeListener方法。他們分別用來設定行為是否可用、判斷行為可用的狀態、設定和取得行為的一些屬性,最後兩個方法用來允許其他對象在行動對象的屬性發生變化後得到通知。
通常我們使用一個實現了Action介面的大部分方法的抽象類別AbstractAction類作為基類,重載actionPerformed方法以實現我們的行為。
我們用一個例子來具體說明如何進行實際的操作。
首先編寫一個具體的行為,對指定的鍵盤事件進行處理:
public class TextAction extends AbstractAction
{
private String a;
public TextAction(String a)
{ this.a = a; }
public void actionPerformed(ActionEvent parm1)
{
String b = parm1.getActionCommand(); //得到行為的命令字串
System.out.println("command="+b);
System.out.println("prompt="+this.a);
}
}