3.2.2 解决方法
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
| /** 工具栏 JToolBar 采用从左开始的 FlowLayout 布局 */
JToolBar toolBar = new JToolBar();
toolBar.setBorderPainted(false); // 不画边界
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
/** 窗体采用动态的 BorderLayout 布局,通过获取工具栏或状态栏的复选标记进行界面的动态调整 */
JSplitPane splitPane = new JSplitPane();
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); // 设置统计窗口分隔条的方向
splitPane.setDividerLocation(300); // 设置分隔条的位置
splitPane.setOneTouchExpandable(true);
JCheckBoxMenuItem toolBarItem = new JCheckBoxMenuItem("工具栏 (T)", true);
JLabel statusLabel = new JLabel("当前统计目标 :");
JCheckBoxMenuItem statusBarItem = new JCheckBoxMenuItem("状态栏 (S)", true);
/** 设置系统窗体布局并动态设置工具栏和状态栏 */
private void setLayout()
{
if (toolBarItem.getState() &&' statusBarItem.getState())
{
this.getContentPane().add(BorderLayout.NORTH, toolBar);
this.getContentPane().add(BorderLayout.CENTER, splitPane);
this.getContentPane().add(BorderLayout.SOUTH, statusLabel);
}
else if (toolBarItem.getState() && !statusBarItem.getState())
{
this.getContentPane().add(BorderLayout.NORTH, toolBar);
this.getContentPane().remove(statusLabel);
}
else if (statusBarItem.getState() && !toolBarItem.getState())
{
this.getContentPane().add(BorderLayout.SOUTH, statusLabel);
this.getContentPane().remove(toolBar);
}
else if (!toolBarItem.getState() && !statusBarItem.getState())
{
this.getContentPane().remove(toolBar);
this.getContentPane().remove(statusLabel);
}
this.show(); // 添加或移去组件后刷新界面
}
|
通过该方法即可实现界面的动态刷新与调整。
3.3 GridBagLayout 应用实例3.3.1 实际问题
GridBagLayout 是 Java API 提供的一个较复杂的布局管理器,利用好它可以解决许多实际编程中的令人烦恼的界面设计问题。看下面的界面应用实例:
3.3.2 解决方法
这个界面的设计比较复杂,涉及多个标签域(JLabel)、文本域(JTextField、JTextArea),且标签域的大小还不一样,如附件标签;并当窗体缩放时,标签域的大小应不改变,而文本域则必须自适应缩放。如何来实现呢?请看下面的代码:(工具栏的实现不再赘述)
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
| /** 系统的界面布局实现 */
GridBagConstraints gridBag = new GridBagConstraints();
gridBag.fill = GridBagConstraints.HORIZONTAL; // 以水平填充方式布局
gridBag.weightx = 0; // 行长不变
gridBag.weighty = 0; // 列高不变
fromLabel.setForeground(Color.blue);
fromLabel.setFont(new Font("Alias", Font.BOLD, 16));
this.add(fromLabel, gridBag, 0, 1, 1, 1); // 指定发信人标签位置
receiveLabel.setForeground(Color.blue);
receiveLabel.setFont(new Font("Alias", Font.BOLD, 16));
this.add(receiveLabel, gridBag, 0, 2, 1, 1); // 指定收信人标签位置及大小
ccLabel.setForeground(Color.blue);
ccLabel.setFont(new Font("Alias", Font.BOLD, 16));
this.add(ccLabel, gridBag, 0, 3, 1, 1); // 指定抄送人标签位置及大小
subjectLabel.setForeground(Color.blue);
subjectLabel.setFont(new Font("Alias", Font.BOLD, 16));
his.add(subjectLabel, gridBag, 0, 4, 1, 1); // 指定主题标签位置及大小
accessoryLabel.setForeground(Color.blue);
accessoryLabel.setFont(new Font("Alias", Font.BOLD, 16));
this.add(accessoryLabel, gridBag, 0, 5, 1, 1); // 指定附件标签位置及大小
gridBag.weightx = 100; // 行自适应缩放
gridBag.weighty = 0;// 列高不变
fromField.setText("admin@watermelon.com");
this.add(fromField, gridBag, 1, 1, 2, 1); // 指定发信人文本域(JTextField)位置及大小
this.add(receiveField, gridBag, 1, 2, 2, 1); // 指定收信人文本域(JTextField)位置及大小
this.add(ccField, gridBag, 1, 3, 2, 1); // 指定抄送人文本域(JTextField)位置及大小
this.add(subjectField, gridBag, 1, 4, 2, 1); // 指定主题文本域(JTextField)位置及大小
accessoryArea.setEditable(false);
// 设置不显示水平滚动条(该 JTextArea 置于 JScrollPane 中)
accessoryScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this.add(accessoryScroll, gridBag, 1, 5, 2, 1); // 指定附件文本区(JTextArea)位置及大小
gridBag.fill = GridBagConstraints.BOTH;// 采用全填充方式布局
gridBag.weightx = 100;// 行自适应缩放
gridBag.weighty = 100;// 列自适应缩放
mailArea.setBackground(Color.blue);
mailArea.setForeground(Color.yellow);
mailArea.setTabSize(4);
// 指定信件主体区(JTextArea)的位置及大小。(该 JTextArea 也置于 JScrollPane 中)
this.add(scroll, gridBag, 0, 6, 3, 1);
在上面用到一个方法 add(),这个方法是自己定义的:
private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h)
{
gbc.gridx = x;
gbc.gridy = y;
gbc.gridheight = h;
gbc.gridwidth = w;
this.getContentPane().add(c, gbc);
}
|
在用到 GridBagLayout 布局管理器的组件添加方法中,都可以重用它。事实上,你还可以在方法最前面加一个参数 Container cn,而将方法中的 this 相应的改为 cn,就可以通用于所有需要使用 GridBagLayout 进行布局管理的容器中。在下面的复杂例程中我们就会用到。 |