在java Swing編程過程中
經常需要處理鍵盤事件
例如處理快捷鍵等
這裡就介紹如何定義鍵盤事件
以及如何處理這些事件
在jdk
中
分別針對Jcomponent和Text類的對象定制了不同的處理鍵盤事件的方法
在Jcomponent中
定義了registerKeyboardAction方法
使用這個方法來將需要處理的鍵盤事件以及處理事件的行為綁定在一起
Text類中具有keymap對象
同Jcomponent中的處理方法類似
這個對象保存著需要處理的鍵盤事件和對應的行為
而在jdk
中
使用一種新的方法來處理鍵盤事件
它將jdk
的兩種方法整合在一起
不需要區分被處理的是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
組件本身擁有焦點時的InputMap
當組件擁有焦點時
鍵盤按鍵按下
則java在這個InputMap中查找鍵盤事件所對應的KeyStroke對象
組件的祖先擁有焦點時的InputMap
當組件的祖先擁有焦點時
鍵盤按鍵按下
則java查找這個InputMap
組件所在的窗口擁有焦點時的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接口中定義了
個方法
其中最關鍵的是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 parm
)
{
String b = parm
getActionCommand(); //得到行為的命令字符串
System
out
println(
command=
+b);
System
out
println(
prompt=
+this
a);
}
}
建立四個TextAction對象
TextAction whenFocusSon = new TextAction(
focus son
);
TextAction whenFocusFather = new TextAction(
focus father
);
TextAction window = new TextAction(
window
);
TextAction ancestor = new TextAction(
ancestor
);
隨後
在一個窗體中加入兩個面板
名為sonPanel和parentPanel
使得parentPanel是sonPanel的祖先
並在sonPanel中加入一個名為son的button
在parentPanel中加入名為parent的button
在fatherPanel外加入幾個button
得到son組件的三個InputMap
並創建一個名為focusFatherIm的InputMap
使得這個InputMap成為focusIm的parent
//get default inputMap (when focus inputmap) and set a parent InputMap
focusIm = son
getInputMap();
focusFatherIm = new InputMap();
focusIm
setParent(focusFatherIm);
//get WHEN_ANCESTOR_OF_FOCUSED_COMPONENT inputMap
ancestorIm = son
getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
//get WHEN_IN_FOCUSED_WINDOW inputMap
windowIm = son
getInputMap(WHEN_IN_FOCUSED_WINDOW);
在這些InputMap中分別加入鍵盤綁定
focusIm
put(KeyStroke
getKeyStroke(
f
)
actionFocusSon
);
focusFatherIm
put(KeyStroke
getKeyStroke(
F
)
actionFocusFather
);
ancestorIm
put(KeyStroke
getKeyStroke(
a
)
actionAncestor
);
windowIm
put(KeyStroke
getKeyStroke(
w
)
actionWindow
);
得到son組件的缺省的ActionMap
並將已經建立的行為與特定的對象(字符串)進行綁定
am = son
getActionMap();
am
put(
actionFocusSon
whenFocusSon);
am
put(
actionFocusFather
whenFocusFather);
am
put(
actionAncestor
ancestor);
am
put(
actionWindow
window);
運行程序及其相應結果
單擊son按鈕
這時如果按下
f
F
a
w
程序均會有相應的輸出
這是因為
此時的焦點在son按鈕上
而son按鈕組件的三個InputMap都是有效的
所以他們對應的事件都會發生
單擊parent按鈕
這時按下
w
程序會有相應的輸出
而按下
f
F
a
程序沒有反應
這是因為parent按鈕具有焦點
這個按鈕不是son按鈕的祖先
而son所在的窗口具有焦點
所以只有組件所在窗口具有焦點的InputMap是有效的
單擊其他的按鈕(parentPanel外的按鈕)
這時按下
w
程序會有相應的輸出
而按下
f
F
a
程序沒有反應
這是因為這些按鈕具有焦點
他們不是son按鈕的祖先
而son所在的窗口具有焦點
所以只有組件所在窗口具有焦點的InputMap是有效的
附
主要程序代碼
import java
awt
*;
import javax
swing
*;
import com
borland
jbcl
layout
*;
import java
awt
event
ActionEvent;
import java
awt
event
ActionListener;
import com
sun
java
swing
plaf
motif
*;
public class EventPanel extends JPanel implements ActionListener
{
JButton btnYellow = new JButton();
JButton btnBlue = new JButton();
JButton btnRed = new JButton();
JPanel parentPanel = new JPanel();
JPanel sonPanel = new JPanel();
XYLayout xYLayout
= new XYLayout();
JButton son = new JButton();
JButton parent = new JButton();
public EventPanel()
{
try{
jbInit();
}catch(Exception ex)
{ ex
printStackTrace(); }
}
void jbInit() throws Exception
{
btnYellow
setText(
Yellow
);
btnYellow
setBounds(new Rectangle(
));
this
setLayout(null);
btnBlue
setBounds(new Rectangle(
));
btnBlue
setText(
Blue
);
btnRed
setBounds(new Rectangle(
));
btnRed
setText(
Red
);
parentPanel
setBorder(BorderFactory
createRaisedBevelBorder());
parentPanel
setBounds(new Rectangle(
));
parentPanel
setLayout(xYLayout
);
sonPanel
setBorder(BorderFactory
createLoweredBevelBorder());
son
setText(
son
);
parent
setText(
parent
);
this
add(btnYellow
null);
this
add(btnBlue
null);
this
add(btnRed
null);
this
add(parentPanel
null);
parentPanel
add(sonPanel
new XYConstraints(
));
sonPanel
add(son
null);
parentPanel
add(parent
new XYConstraints(
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25647.html