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组件提供快捷键

典型用法如下:

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

程序 Swing快捷键

下面程序实现这样一个功能:用户在单行文本框内输入内容,当输入完成后,单击后面的“发送”按钮即可将文本框的内容添加到一个多行文本域中;或者输入完成后在文本框内按“Ctrl+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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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,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();
}
}

上面程序中的代码:

// 将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);

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