12.2.5 使用JToolBar创建工具条

12.2.5 使用JToolBar创建工具条

构造器

Swing提供了JToolBar类来创建工具条:

方法 描述
JToolBar() Creates a new tool bar; orientation defaults to HORIZONTAL.
JToolBar(int orientation) Creates a new tool bar with the specified orientation.
JToolBar(String name) Creates a new tool bar with the specified name.
JToolBar(String name, int orientation) Creates a new tool bar with a specified name and orientation.

创建JToolBar对象时可以指定如下两个参数:

  • name:该参数指定该工具条的名称
  • orientation:该参数指定该工具条的方向。

JToolBar常用方法

一旦创建了JToolBar对象之后,JToolBar对象还有如下几个常用方法:

方法 描述
JButton add(Action a) 通过Action对象为JToolBar添加对应的工具按钮。
void addSeparator() 添加一个默认大小的分隔符
void addSeparator(Dimension size) 向工具条中添加指定大小的分隔符
void setFloatable(boolean b) 设置该工具条是否可浮动,即该工具条是否可以拖动
void setMargin(Insets m) 设置工具条边框和工具按钮之间的页边距
void setOrientation(int o) 设置工具条的方向
void setRollover(boolean rollover) 设置此工具条的rollover状态

Action接口

上面的大多数方法都比较容易理解,比较难以理解的是add方法,系统如何为工具条添加Action对应的按钮呢?

Action接口是ActionListener接口的子接口,它除包含ActionListener接口的actionPerformed()方法之外,还包含nameicon两个属性,其中name用于指定按钮或菜单项中的文本,而icon则用于指定按钮的图标或菜单项中的图标。也就是说,Action不仅可作为事件监听器使用,而且可被转换成按钮或菜单项

值得指出的是,Action本身并不是按钮,也不是菜单项,只是当把Action对象添加到某些容器(也可直接使用Action来创建按钮),如菜单和工具栏中时,这些容器会为该Action对象创建对应的组件(菜单项和按钮)。也就是说,这些容器需要负责完成如下事情。

  • 创建一个适用于该容器的组件(例如,在工具栏中创建一个工具按钮)
  • Action对象中获得对应的属性来设置该组件(例如,通过name来设置文本,通过icon来设置图标)。
  • 检查Action对象的初始状态,确定它是否处于激活状态,并根据该Action的状态米决定其对应所有组件的行为。只有处于激活状态的Action所对应的Swing组件才可以响应用户动作。
  • 通过Action对象为对应组件注册事件监听器,系统将为该Action所创建的所有组件注册同一个事件监听器(事件处理器就是Action对象里的actionPerformed方法)

程序

例如,程序中有一个菜单项、一个工具按钮,还有一个普通按钮都需要完成某个“复制”动作,程序就可以将该“复制”动作定义成Action,并为之指定nameicon属性,然后通过该Action来创建菜单项、工具按钮和普通按钮,就可以让这三个组件具有相同的功能。另一个“粘贴”按钮也大致相似,而且“粘贴”组件默认不可用,只有当“复制”组件被触发后,且剪贴板中有内容时才可用。

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.*;

public class JToolBarTest {
JFrame jFrame = new JFrame("测试工具条");
JTextArea jTextArea = new JTextArea(6, 35);
JToolBar jToolBar = new JToolBar();
JMenuBar jMenuBar = new JMenuBar();
JMenu editMenu = new JMenu("编辑");
// 获取系统剪贴板
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
// 创建"粘贴"Action,该Action用于创建菜单项、工具按钮和普通按钮
Action pasteAction = new AbstractAction("粘贴", new ImageIcon("ico/paste.png")) {
private static final long serialVersionUID = 3517594171860327637L;

public void actionPerformed(ActionEvent e) {
// 如果剪贴板中包含stringFlavor内容
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
try {
// 取出剪贴板中stringFlavor内容
String content = (String) clipboard.getData(DataFlavor.stringFlavor);
// 将选中内容替换成剪贴板中的内容
jTextArea.replaceRange(content, jTextArea.getSelectionStart(), jTextArea.getSelectionEnd());
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
};
// 创建"复制"Action
Action copyAction = new AbstractAction("复制", new ImageIcon("ico/copy.png")) {
private static final long serialVersionUID = 8903877264455460708L;

public void actionPerformed(ActionEvent e) {
StringSelection contents = new StringSelection(jTextArea.getSelectedText());
// 将StringSelection对象放入剪贴板
clipboard.setContents(contents, null);
// 如果剪贴板中包含stringFlavor内容
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
// 将pasteAction激活
pasteAction.setEnabled(true);
}
}
};

public void init() {
// pasteAction默认处于不激活状态
pasteAction.setEnabled(false); // 1
jFrame.add(new JScrollPane(jTextArea));
// 以Action创建按钮,并将该按钮添加到Panel中
JButton copyBn = new JButton(copyAction);
JButton pasteBn = new JButton(pasteAction);
JPanel jp = new JPanel();
jp.add(copyBn);
jp.add(pasteBn);
jFrame.add(jp, BorderLayout.SOUTH);
// 向工具条中添加Action对象,该对象将会转换成工具按钮
jToolBar.add(copyAction);
jToolBar.addSeparator();
jToolBar.add(pasteAction);
// 向菜单中添加Action对象,该对象将会转换成菜单项
editMenu.add(copyAction);
editMenu.add(pasteAction);
// 将edit菜单添加到菜单条中
jMenuBar.add(editMenu);
jFrame.setJMenuBar(jMenuBar);
// 设置工具条和工具按钮之间的页边距。
jToolBar.setMargin(new Insets(5, 5, 5, 5)); // 2
// 向窗口中添加工具条
jFrame.add(jToolBar, BorderLayout.NORTH);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.pack();
jFrame.setVisible(true);
}

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

上面程序中创建了pasteActioncopyAction两个Action,然后根据这两个Action分别创建了按钮工具按钮菜单项组件,开始时pasteAction处于非激活状态,则该Action对应的按钮工具按钮菜单项都处于不可用状态。运行上面程序,会看到如图12.7所示的界面

这里有一张图片

图12.7显示了工具条被拖动后的效果,这是因为工具条默认处于浮动状态。除此之外,程序中 2 号代码设置了工具条和工具按钮之间的页边距,所以可以看到工具条在工具按钮周围保留了一些空白区域。