12.2.4 Swing组件的双缓冲和键盘驱动

12.2.4 Swing组件的双缓冲和键盘驱动

除此之外,Swing组件还有如下两个功能:

  • 所有的Swing组件默认启用双缓冲绘图技术
  • 所有的Swing组件都提供了简单的键盘驱动

Swing组件默认启用双缓冲绘图技术,使用双缓冲技术能改进频繁重绘GUI组件的显示效果(避免闪烁现象)。JComponent组件默认启用双缓冲,无须自己实现双缓冲。如果想关闭双缓冲,可以在组件上调用setDoubleBuffered(false)方法。前一章介绍五子棋游戏时已经提到Swing组件的双缓冲技术,而且可以使用JPanel代替前一章所有示例程序中的Canvas画布组件,从而可以解决运行那些示例程序时的“闪烁”现象。
JComponent类提供了getInputMap()getActionMap()两个方法,其中

方法 描述
getInputMap() 返回一个InputMap对象,该对象用于将KeyStroke对象和名字关联,KeyStroke代表键盘或其他类似输入设备的一次输入事件;
getActionMap() 返回一个ActionMap对象,该对象用于将指定名字和Action关联,Action接口是ActionListener接口的子接口,可作为一个事件监听器使用,从而可以允许用户通过键盘操作来替代鼠标驱动GUI上的Swing组件,相当于为GUI组件提供快捷键

典型用法如下:

1
2
3
4
//把一次键盘事件和一个aCommand象关联
component.getInputMap().put(aKeystroke,aCommand);
//将 command对象和anAction事件响应关联
component.getActionMap().put(aCommmand,anAction);

程序 Swing快捷键

下面程序实现这样一个功能:用户在单行文本框内输入内容,当输入完成后,单击后面的“发送”按钮即可将文本框的内容添加到一个多行文本域中;或者输入完成后在文本框内按“Crl+Enter”键也可以将文本框的内容添加到一个多行文本域中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class BindKeyTest {
JFrame jFrame = new JFrame("测试键盘绑定");
JTextArea jTextArea = new JTextArea(5, 30);
JButton jButton = new JButton("发送");
JTextField jTextField = new JTextField(15);

public void init() {
jFrame.add(jTextArea);
JPanel jp = new JPanel();
jp.add(jTextField);
jp.add(jButton);
jFrame.add(jp, BorderLayout.SOUTH);
// 发送消息的Action,Action是ActionListener的子接口
Action sendMsg = new AbstractAction() {
private static final long serialVersionUID = 2625520225836946219L;

public void actionPerformed(ActionEvent e) {
jTextArea.append(jTextField.getText() + "\n");
jTextField.setText("");
}
};
// 添加事件监听器
jButton.addActionListener(sendMsg);
// 将Ctrl+Enter键和"send"关联
jTextField.getInputMap().put(KeyStroke.getKeyStroke('\n', java.awt.event.InputEvent.CTRL_DOWN_MASK), "send");
// 将"send"和sendMsg Action关联
jTextField.getActionMap().put("send", sendMsg);
jFrame.pack();
jFrame.setVisible(true);
}

public static void main(String[] args) {
new BindKeyTest().init();
}
}

上面程序中粗体字代码示范了如何利用键盘事件来驱动Swing组件,采用这种键盘事件机制,无须为Swing组件绑定键盘监听器,从而可以复用按钮单击事件的事件监听器,程序十分简洁。