对于初学 Java Swing 的开发人员来说,控件的布局是比较困难的。相对于 FlowLayout 而言,BoxLayout 比较灵活,有更大的功能,可以完成比较复杂界面的布局,本文将在基于例子的基础上给出如何较好的使用 BoxLayout, 可以给 Java Swing 的初学者一些启发。
在用户使用 Java Swing 进行用户界面开发过程中,会碰到如何对 Java Swing 的控件进行布局的问题。Swing 的控件放置在容器 (Container) 中,容器就是能够容纳控件或者其它容器的类,容器的具体例子有 Frame、Panel 等等。容器需要定义一个布局管理器来对控件进行布局管理,Swing 当中提供的主要的布局管理器有 FlowLayout、BorderLayout、BoxLayout、GridLayout 和 GridBaglayout, 它们的主要特点如表 1 所示:
布局管理器 | 特点 |
---|---|
FlowLayout | 把控件按照顺序一个接一个由左向右的水平放置在容器中,一行放不下,就放到下一行 |
BorderLayout | 将整个容器划分成东南西北中五个方位来放置控件,放置控件时需要指定控件放置的方位 |
BoxLayout | 可以指定在容器中是否对控件进行水平或者垂直放置,比 FlowLayout 要更为灵活 |
GridLayout | 将整个容器划分成一定的行和一定的列,可以指定控件放在某行某列上 |
GridBagLayout | 是 Swing 当中最灵活也是最复杂的布局管理器,可对控件在容器中的位置进行比较灵活的调整 |
本文主要关注在 BoxLayout 布局管理器的使用上。我们首先对 BoxLayout 作一下介绍。
如前所述,BoxLayout 可以把控件依次进行水平或者垂直排列布局,这是通过参数 X_AXIS、Y_AXIS 来决定的。X_AXIS 表示水平排列,而 Y_AXIS 表示垂直排列。BoxLayout 的构造函数有两个参数,一个参数定义使用该 BoxLayout 的容器,另一个参数是指定 BoxLayout 是采用水平还是垂直排列。下面是一个创建 BoxLayout 实例的例子:
1 JPanel panel=new JPanel(); 2 BoxLayout layout=new BoxLayout(panel, BoxLayout.X_AXIS); 3 panel.setLayout(layoout);
在这个例子中,一个 BoxLayout 布局管理器的实例 layout 被创建,这个实例被设置为 panel 的布局管理器,该布局管理器采用了水平排列来排列控件。
当 BoxLayout 进行布局时,它将所有控件依次按照控件的优先尺寸按照顺序的进行水平或者垂直放置,假如布局的整个水平或者垂直空间的尺寸不能放下所有控件,那么 BoxLayout 会试图调整各个控件的大小来填充整个布局的水平或者垂直空间。
BoxLayout 往往和 Box 这个容器结合在一起使用,这么做的理由是,BoxLayout 是把控件以水平或者垂直的方向一个接一个的放置,如果要调整这些控件之间的空间,就会需要使用 Box 容器提供的透明的组件作为填充来填充控件之间的空间,从而达到调整控件之间的间隔空间的目的。Box 容器提供了 4 种透明的组件,分别是 rigid area、strut、glue、filler。Box 容器分别提供了不同的方法来创建这些组件。这四个组件的特点如下:
在了解了 BoxLayout 和 Box 容器的基本特点后,我们来看一下 BoxLayout 的优点,首先 BoxLayout 可以进行对控件进行垂直或者水平布局,同时 BoxLayout 使用起来较为简单,然而把它和 Box 容器相结合,就可以进行较为复杂的布局,达到同使用 GridBagLayout 的一样的效果,但是使用起来要简单方便多了。我们用按钮的布局作为例子来看怎样运用 BoxLayout 和 Box 容器进行布局:
我们在布局中经常会碰到如图 1 所示要把按钮放在容器的两端,那么我们就可以给容器定义一个 BoxLayout 来布局按钮,我们在按钮 1 和按钮 2 之间放置一个不可见的 glue,如前面所提到的那样,glue 就会尽量挤占掉两个按钮之间的空间,从而将两个按钮放在两端。
再来看图 2 的例子,我们经常会遇到要将两个按钮放在容器的右边,我们就可以给容器定义一个 BoxLayout, 先放一个不可见的 glue,这个 glue 会挤占左边的空间,从而将两个按钮推到右边,
在两个按钮之间再放一个 strut,它也是不可见的,它会把两个按钮分隔开。
在基于前面讨论的基础上,我们现在来看一个具体的运用例子,假设图 3 是我们需要完成的用户界面:
这个演示是一个虚拟的用户对话框,只用于演示如何使用 BoxLayout, 例子代码中没有实现控件的动作。我们假定通过它用户可以选择要查询的运动会项目,然后查询,对话框中的表格显示了查询到的运动会项目的报名情况。为了完成这个布局,我们从上到下分别定义了 3 个 Panel, 分别叫做 topPanel,middlePanel,bottomPanel,这 3 个 Panel 都使用 BoxLayout。我们先看最上边的 topPanel,也就是包含表格的 Panel,topPanel 布局的基本思路是该 Panel 采用 BoxLayout 的垂直排列布局,先放置一个不可见的 Strut, 使
topPanel 相 对顶部留出一定的空间,
再放置包含表格的滚动窗格,再加入一个不可见的
Strut,从而使
topPanel和
middlePanel之间留出一定的空间。
TopPanel 的代码如清单 1 所示:
1 static void createTopPanel() { 2 topPanel = new JPanel(); 3 String[] columnName = { "姓名", "性别", "单位", "参加项目", "备注" }; 4 String[][] rowData = { { "张三", "男", "计算机系", "100 米 ,200 米", "" }, { "李四", "男", "化学系", "100 米,铅球", "" }, }; 5 // 创建表格 6 JTable table = new JTable(new DefaultTableModel(rowData, columnName)); 7 // 创建包含表格的滚动窗格 8 JScrollPane scrollPane = new JScrollPane(table); 9 scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 10 // 定义 topPanel 的布局为 BoxLayout,BoxLayout 为垂直排列 11 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); 12 // 先加入一个不可见的 Strut,从而使 topPanel 对顶部留出一定的空间 13 topPanel.add(Box.createVerticalStrut(10)); 14 // 加入包含表格的滚动窗格 15 topPanel.add(scrollPane); 16 // 再加入一个不可见的 Strut,从而使 topPanel 和 middlePanel 之间留出一定的空间 17 topPanel.add(Box.createVerticalStrut(10)); 18 }
位于中间的 middlePanel 比较复杂些,它的左边包括标签运动会项目和运动会项目列表,中间是两个按钮,我们假定点击 >> 按钮将会把用户在运动会项目列表中选中的项目移到右边的查询项目列表,点击 << 按钮则将右边查询项目列表中选中的项目移回到左边的运动会项目列表。它的布局的基本思路是定义了三个子 Panel,这三个子 Panel 分别对应最左边的标签和运动会项目列表,中间的两个按钮,和最右边的标签和查询项目列表,最左边的 Panel 采用 BoxLayout 的水平排列布局,中间的 Panel 采用 BoxLayout 的垂直排列布局,两个按钮之间加入一个不可见的 rigidArea,调整两个按钮之间的垂直距离,最右边的 Panel 采用 BoxLayout 的水平排列布局放置标签和查询项目列表。然后采用水平排列布局的 middlePanel 将三个 Panel 依次水平的加入。 MiddlePanel 的代码如清单 2 所示。
1 static void createMiddlePanel() { 2 // 创建 middlePanel 3 middlePanel = new JPanel(); 4 // 采用水平布局 5 middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.X_AXIS)); 6 // 创建标签运动会项目 7 JLabel sourceLabel = new JLabel("运动会项目:"); 8 sourceLabel.setAlignmentY(Component.TOP_ALIGNMENT); 9 sourceLabel.setBorder(BorderFactory.createEmptyBorder(4, 5, 0, 5)); 10 // 创建列表运动会项目 11 DefaultListModel listModel = new DefaultListModel(); 12 listModel.addElement("100 米"); 13 listModel.addElement("200 米"); 14 listModel.addElement("400 米"); 15 listModel.addElement("跳远"); 16 listModel.addElement("跳高"); 17 listModel.addElement("铅球"); 18 JList sourceList = new JList(listModel); 19 sourceList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 20 sourceList.setVisibleRowCount(5); 21 JScrollPane sourceListScroller = new JScrollPane(sourceList); 22 sourceListScroller.setPreferredSize(new Dimension(120, 80)); 23 sourceListScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 24 sourceListScroller.setAlignmentY(Component.TOP_ALIGNMENT); 25 // 创建最左边的 Panel 26 JPanel sourceListPanel = new JPanel(); 27 // 最左边的 Panel 采用水平布局 28 sourceListPanel.setLayout(new BoxLayout(sourceListPanel, BoxLayout.X_AXIS)); 29 // 加入标签到最左边的 Panel 30 sourceListPanel.add(sourceLabel); 31 // 加入列表运动会项目到最左边的 Panel 32 sourceListPanel.add(sourceListScroller); 33 sourceListPanel.setAlignmentY(Component.TOP_ALIGNMENT); 34 sourceListPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 30)); 35 // 将最左边的 Panel 加入到 middlePanel 36 middlePanel.add(sourceListPanel); 37 // 定义中间的两个按钮 38 JButton toTargetButton = new JButton(">>"); 39 JButton toSourceButton = new JButton("<<"); 40 // 定义中间的 Panel 41 JPanel buttonPanel = new JPanel(); 42 // 中间的 Panel 采用水平布局 43 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); 44 // 将按钮 >> 加入到中间的 Panel 45 buttonPanel.add(toTargetButton); 46 47 // 两个按钮之间加入一个不可见的 rigidArea 48 buttonPanel.add(Box.createRigidArea(new Dimension(15, 15))); 49 // 将按钮 << 加入到中间的 Panel 50 buttonPanel.add(toSourceButton); 51 buttonPanel.setAlignmentY(Component.TOP_ALIGNMENT); 52 buttonPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 5)); 53 // 将中间的 Panel 加入到 middlePanel 54 middlePanel.add(buttonPanel); 55 // 创建标签查询项目 56 JLabel targetLabel = new JLabel("查询项目:"); 57 targetLabel.setAlignmentY(Component.TOP_ALIGNMENT); 58 targetLabel.setBorder(BorderFactory.createEmptyBorder(4, 5, 0, 5)); 59 60 // 创建列表查询项目 61 DefaultListModel targetListModel = new DefaultListModel(); 62 targetListModel.addElement("100 米"); 63 JList targetList = new JList(targetListModel); 64 targetList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 65 targetList.setVisibleRowCount(5); 66 JScrollPane targetListScroller = new JScrollPane(targetList); 67 targetListScroller.setPreferredSize(new Dimension(120, 80)); 68 targetListScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 69 targetListScroller.setAlignmentY(Component.TOP_ALIGNMENT); 70 // 创建最右边的 Panel 71 JPanel targetListPanel = new JPanel(); 72 // 设置最右边的 Panel 为水平布局 73 targetListPanel.setLayout(new BoxLayout(targetListPanel, BoxLayout.X_AXIS)); 74 // 将标签查询项目加到最右边的 Panel 75 targetListPanel.add(targetLabel); 76 // 将列表查询项目加到最右边的 Panel 77 targetListPanel.add(targetListScroller); 78 targetListPanel.setAlignmentY(Component.TOP_ALIGNMENT); 79 targetListPanel.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); 80 // 最后将最右边的 Panel 加入到 middlePanel 81 middlePanel.add(targetListPanel); 82 }
我们最后来看一下 bottomPanel 如何布局,bottomPanel 包括分布在两边的两个按钮,其实 bottomPanel 的布局和章节用 BoxLayout 进行布局中的图 1 是一致的,我们在两个按钮之间加入一个 glue, 这个 glue 会挤占两个按钮之间的空间,从而将两个按钮布局到两边,在 bottemPanel 中用一个 buttonPanel 来放置这两个按钮。BottomPanel 采用 BoxLayout, 首先放入一个 strut, 从而使 bottomPanel 和 middlePanel 之间留出距离,再放入 buttonPanel,再放入一个 strut, 从而使 bottomPanel 和底部之间留出距离,BottomPanel 的代码如清单 3 所示。
1 static void createBottomPanel() { 2 // 创建查询按钮 3 JButton actionButton = new JButton("查询"); 4 // 创建退出按钮 5 JButton closeButton = new JButton("退出"); 6 // 创建 bottomPanel 7 bottomPanel = new JPanel(); 8 // 设置 bottomPanel 为垂直布局 9 bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); 10 // 创建包含两个按钮的 buttonPanel 11 JPanel buttonPanel = new JPanel(); 12 // 设置 bottomPanel 为水平布局 13 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 14 // 将查询按钮加入到 buttonPanel 15 buttonPanel.add(actionButton); 16 17 // 加入一个 glue, glue 会挤占两个按钮之间的空间 18 buttonPanel.add(Box.createHorizontalGlue()); 19 // 将退出按钮加入到 buttonPanel 20 buttonPanel.add(closeButton); 21 // 加入一个 Strut,从而使 bottomPanel 和 middlePanel 上下之间留出距离 22 bottomPanel.add(Box.createVerticalStrut(10)); 23 // 加入 buttonPanel 24 bottomPanel.add(buttonPanel); 25 // 加入一个 Strut,从而使 bottomPanel 和底部之间留出距离 26 bottomPanel.add(Box.createVerticalStrut(10)); 27 }
我们用一个 Panel 来从上到下放置 topPanel、middlePanel 和 bottomPanel,这个 Panel 采用了 GridBagLayout, 最后我们将这个 Panel 加到一个窗体中去,请参考清单 4。
1 public static void main(String[] args) { 2 BoxLayoutDemo.init(); 3 } 4 5 public static void init() { 6 // 创建 topPanel 7 createTopPanel(); 8 // 创建 middlePanel 9 createMiddlePanel(); 10 // 创建 bottomPanel 11 createBottomPanel(); 12 // 创建包含 topPanel,middlePanel 和 bottomPanel 的 panelContainer 13 JPanel panelContainer = new JPanel(); 14 // panelContainer 的布局为 GridBagLayout 15 panelContainer.setLayout(new GridBagLayout()); 16 17 GridBagConstraints c1 = new GridBagConstraints(); 18 c1.gridx = 0; 19 c1.gridy = 0; 20 c1.weightx = 1.0; 21 c1.weighty = 1.0; 22 c1.fill = GridBagConstraints.BOTH; 23 // 加入 topPanel 24 panelContainer.add(topPanel, c1); 25 26 GridBagConstraints c2 = new GridBagConstraints(); 27 c2.gridx = 0; 28 c2.gridy = 1; 29 c2.weightx = 1.0; 30 c2.weighty = 0; 31 c2.fill = GridBagConstraints.HORIZONTAL; 32 // 加入 middlePanel 33 panelContainer.add(middlePanel, c2); 34 35 GridBagConstraints c3 = new GridBagConstraints(); 36 c3.gridx = 0; 37 c3.gridy = 2; 38 c3.weightx = 1.0; 39 c3.weighty = 0; 40 c3.fill = GridBagConstraints.HORIZONTAL; 41 // 加入 bottomPanel 42 panelContainer.add(bottomPanel, c3); 43 44 // 创建窗体 45 JFrame frame = new JFrame("Boxlayout 演示"); 46 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 47 panelContainer.setOpaque(true); 48 frame.setSize(new Dimension(480, 320)); 49 frame.setContentPane(panelContainer); 50 frame.setVisible(true); 51 }
本文的例子是在文件 BoxLayoutDemo.zip 中,您将其展开,导入到 Eclipse 中去,就可运行例子。
您通过本文的介绍,可以对 BoxLayout 这个布局管理器如何进行布局能够有一定的了解,也可以在自己的实践过程中进一步总结出自己的方法。
最后贴出完整代码
1 package com.wst.bj; 2 3 import java.awt.Component; 4 import java.awt.Dimension; 5 import java.awt.GridBagConstraints; 6 import java.awt.GridBagLayout; 7 8 import javax.swing.BorderFactory; 9 import javax.swing.Box; 10 import javax.swing.BoxLayout; 11 import javax.swing.DefaultListModel; 12 import javax.swing.JButton; 13 import javax.swing.JFrame; 14 import javax.swing.JLabel; 15 import javax.swing.JList; 16 import javax.swing.JPanel; 17 import javax.swing.JScrollPane; 18 import javax.swing.JTable; 19 import javax.swing.ListSelectionModel; 20 import javax.swing.table.DefaultTableModel; 21 22 public class BoxLayoutDemo { 23 24 private static JPanel topPanel; 25 private static JPanel middlePanel; 26 private static JPanel bottomPanel; 27 28 public static void init() { 29 // 创建 topPanel 30 createTopPanel(); 31 // 创建 middlePanel 32 createMiddlePanel(); 33 // 创建 bottomPanel 34 createBottomPanel(); 35 // 创建包含 topPanel,middlePanel 和 bottomPanel 的 panelContainer 36 JPanel panelContainer = new JPanel(); 37 // panelContainer 的布局为 GridBagLayout 38 panelContainer.setLayout(new GridBagLayout()); 39 40 GridBagConstraints c1 = new GridBagConstraints(); 41 c1.gridx = 0; 42 c1.gridy = 0; 43 c1.weightx = 1.0; 44 c1.weighty = 1.0; 45 c1.fill = GridBagConstraints.BOTH; 46 // 加入 topPanel 47 panelContainer.add(topPanel, c1); 48 49 GridBagConstraints c2 = new GridBagConstraints(); 50 c2.gridx = 0; 51 c2.gridy = 1; 52 c2.weightx = 1.0; 53 c2.weighty = 0; 54 c2.fill = GridBagConstraints.HORIZONTAL; 55 // 加入 middlePanel 56 panelContainer.add(middlePanel, c2); 57 58 GridBagConstraints c3 = new GridBagConstraints(); 59 c3.gridx = 0; 60 c3.gridy = 2; 61 c3.weightx = 1.0; 62 c3.weighty = 0; 63 c3.fill = GridBagConstraints.HORIZONTAL; 64 // 加入 bottomPanel 65 panelContainer.add(bottomPanel, c3); 66 67 // 创建窗体 68 JFrame frame = new JFrame("Boxlayout 演示"); 69 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 70 panelContainer.setOpaque(true); 71 frame.setSize(new Dimension(480, 320)); 72 frame.setContentPane(panelContainer); 73 frame.setVisible(true); 74 } 75 76 static void createTopPanel() { 77 topPanel = new JPanel(); 78 String[] columnName = { "姓名", "性别", "单位", "参加项目", "备注" }; 79 String[][] rowData = { { "张三", "男", "计算机系", "100 米 ,200 米", "" }, { "李四", "男", "化学系", "100 米,铅球", "" }, }; 80 // 创建表格 81 JTable table = new JTable(new DefaultTableModel(rowData, columnName)); 82 // 创建包含表格的滚动窗格 83 JScrollPane scrollPane = new JScrollPane(table); 84 scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 85 // 定义 topPanel 的布局为 BoxLayout,BoxLayout 为垂直排列 86 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); 87 // 先加入一个不可见的 Strut,从而使 topPanel 对顶部留出一定的空间 88 topPanel.add(Box.createVerticalStrut(10)); 89 // 加入包含表格的滚动窗格 90 topPanel.add(scrollPane); 91 // 再加入一个不可见的 Strut,从而使 topPanel 和 middlePanel 之间留出一定的空间 92 topPanel.add(Box.createVerticalStrut(10)); 93 } 94 95 static void createMiddlePanel() { 96 // 创建 middlePanel 97 middlePanel = new JPanel(); 98 // 采用水平布局 99 middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.X_AXIS)); 100 // 创建标签运动会项目 101 JLabel sourceLabel = new JLabel("运动会项目:"); 102 sourceLabel.setAlignmentY(Component.TOP_ALIGNMENT); 103 sourceLabel.setBorder(BorderFactory.createEmptyBorder(4, 5, 0, 5)); 104 // 创建列表运动会项目 105 DefaultListModel listModel = new DefaultListModel(); 106 listModel.addElement("100 米"); 107 listModel.addElement("200 米"); 108 listModel.addElement("400 米"); 109 listModel.addElement("跳远"); 110 listModel.addElement("跳高"); 111 listModel.addElement("铅球"); 112 JList sourceList = new JList(listModel); 113 sourceList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 114 sourceList.setVisibleRowCount(5); 115 JScrollPane sourceListScroller = new JScrollPane(sourceList); 116 sourceListScroller.setPreferredSize(new Dimension(120, 80)); 117 sourceListScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 118 sourceListScroller.setAlignmentY(Component.TOP_ALIGNMENT); 119 // 创建最左边的 Panel 120 JPanel sourceListPanel = new JPanel(); 121 // 最左边的 Panel 采用水平布局 122 sourceListPanel.setLayout(new BoxLayout(sourceListPanel, BoxLayout.X_AXIS)); 123 // 加入标签到最左边的 Panel 124 sourceListPanel.add(sourceLabel); 125 // 加入列表运动会项目到最左边的 Panel 126 sourceListPanel.add(sourceListScroller); 127 sourceListPanel.setAlignmentY(Component.TOP_ALIGNMENT); 128 sourceListPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 30)); 129 // 将最左边的 Panel 加入到 middlePanel 130 middlePanel.add(sourceListPanel); 131 // 定义中间的两个按钮 132 JButton toTargetButton = new JButton(">>"); 133 JButton toSourceButton = new JButton("<<"); 134 // 定义中间的 Panel 135 JPanel buttonPanel = new JPanel(); 136 // 中间的 Panel 采用水平布局 137 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); 138 // 将按钮 >> 加入到中间的 Panel 139 buttonPanel.add(toTargetButton); 140 141 // 两个按钮之间加入一个不可见的 rigidArea 142 buttonPanel.add(Box.createRigidArea(new Dimension(15, 15))); 143 // 将按钮 << 加入到中间的 Panel 144 buttonPanel.add(toSourceButton); 145 buttonPanel.setAlignmentY(Component.TOP_ALIGNMENT); 146 buttonPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 5)); 147 // 将中间的 Panel 加入到 middlePanel 148 middlePanel.add(buttonPanel); 149 // 创建标签查询项目 150 JLabel targetLabel = new JLabel("查询项目:"); 151 targetLabel.setAlignmentY(Component.TOP_ALIGNMENT); 152 targetLabel.setBorder(BorderFactory.createEmptyBorder(4, 5, 0, 5)); 153 154 // 创建列表查询项目 155 DefaultListModel targetListModel = new DefaultListModel(); 156 targetListModel.addElement("100 米"); 157 JList targetList = new JList(targetListModel); 158 targetList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 159 targetList.setVisibleRowCount(5); 160 JScrollPane targetListScroller = new JScrollPane(targetList); 161 targetListScroller.setPreferredSize(new Dimension(120, 80)); 162 targetListScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 163 targetListScroller.setAlignmentY(Component.TOP_ALIGNMENT); 164 // 创建最右边的 Panel 165 JPanel targetListPanel = new JPanel(); 166 // 设置最右边的 Panel 为水平布局 167 targetListPanel.setLayout(new BoxLayout(targetListPanel, BoxLayout.X_AXIS)); 168 // 将标签查询项目加到最右边的 Panel 169 targetListPanel.add(targetLabel); 170 // 将列表查询项目加到最右边的 Panel 171 targetListPanel.add(targetListScroller); 172 targetListPanel.setAlignmentY(Component.TOP_ALIGNMENT); 173 targetListPanel.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); 174 // 最后将最右边的 Panel 加入到 middlePanel 175 middlePanel.add(targetListPanel); 176 } 177 178 static void createBottomPanel() { 179 // 创建查询按钮 180 JButton actionButton = new JButton("查询"); 181 // 创建退出按钮 182 JButton closeButton = new JButton("退出"); 183 // 创建 bottomPanel 184 bottomPanel = new JPanel(); 185 // 设置 bottomPanel 为垂直布局 186 bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS)); 187 // 创建包含两个按钮的 buttonPanel 188 JPanel buttonPanel = new JPanel(); 189 // 设置 bottomPanel 为水平布局 190 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 191 // 将查询按钮加入到 buttonPanel 192 buttonPanel.add(actionButton); 193 194 // 加入一个 glue, glue 会挤占两个按钮之间的空间 195 buttonPanel.add(Box.createHorizontalGlue()); 196 // 将退出按钮加入到 buttonPanel 197 buttonPanel.add(closeButton); 198 // 加入一个 Strut,从而使 bottomPanel 和 middlePanel 上下之间留出距离 199 bottomPanel.add(Box.createVerticalStrut(10)); 200 // 加入 buttonPanel 201 bottomPanel.add(buttonPanel); 202 // 加入一个 Strut,从而使 bottomPanel 和底部之间留出距离 203 bottomPanel.add(Box.createVerticalStrut(10)); 204 } 205 206 }
原文:http://www.cnblogs.com/LiuYanYGZ/p/6158957.html