摘自http://www.cnblogs.com/fnlingnzb-learner/p/6008572.html

运用 BoxLayout 进行 Swing 控件布局

对于初学 Java Swing 的开发人员来说,控件的布局是比较困难的。相对于 FlowLayout 而言,BoxLayout 比较灵活,有更大的功能,可以完成比较复杂界面的布局,本文将在基于例子的基础上给出如何较好的使用 BoxLayout, 可以给 Java Swing 的初学者一些启发。

引言

在用户使用 Java Swing 进行用户界面开发过程中,会碰到如何对 Java Swing 的控件进行布局的问题。Swing 的控件放置在容器 (Container) 中,容器就是能够容纳控件或者其它容器的类,容器的具体例子有 Frame、Panel 等等。容器需要定义一个布局管理器来对控件进行布局管理,Swing 当中提供的主要的布局管理器有 FlowLayout、BorderLayout、BoxLayout、GridLayout 和 GridBaglayout, 它们的主要特点如表 1 所示:

表 1. Swing 中的一些主要布局管理器的比较
布局管理器 特点
FlowLayout 把控件按照顺序一个接一个由左向右的水平放置在容器中,一行放不下,就放到下一行
BorderLayout 将整个容器划分成东南西北中五个方位来放置控件,放置控件时需要指定控件放置的方位
BoxLayout 可以指定在容器中是否对控件进行水平或者垂直放置,比 FlowLayout 要更为灵活
GridLayout 将整个容器划分成一定的行和一定的列,可以指定控件放在某行某列上
GridBagLayout 是 Swing 当中最灵活也是最复杂的布局管理器,可对控件在容器中的位置进行比较灵活的调整

本文主要关注在 BoxLayout 布局管理器的使用上。我们首先对 BoxLayout 作一下介绍。

BoxLayout 介绍

如前所述,BoxLayout 可以把控件依次进行水平或者垂直排列布局,这是通过参数 X_AXIS、Y_AXIS 来决定的。X_AXIS 表示水平排列,而 Y_AXIS 表示垂直排列。BoxLayout 的构造函数有两个参数,一个参数定义使用该 BoxLayout 的容器,另一个参数是指定 BoxLayout 是采用水平还是垂直排列。下面是一个创建 BoxLayout 实例的例子:

  1. JPanel panel=new JPanel(); BoxLayout layout=new BoxLayout(panel, BoxLayout.X_AXIS); panel.setLayout(layoout);

在这个例子中,一个 BoxLayout 布局管理器的实例 layout 被创建,这个实例被设置为 panel 的布局管理器,该布局管理器采用了水平排列来排列控件。

当 BoxLayout 进行布局时,它将所有控件依次按照控件的优先尺寸按照顺序的进行水平或者垂直放置,假如布局的整个水平或者垂直空间的尺寸不能放下所有控件,那么 BoxLayout 会试图调整各个控件的大小来填充整个布局的水平或者垂直空间。

BoxLayout 往往和 Box 这个容器结合在一起使用,这么做的理由是,BoxLayout 是把控件以水平或者垂直的方向一个接一个的放置,如果要调整这些控件之间的空间,就会需要使用 Box 容器提供的透明的组件作为填充来填充控件之间的空间,从而达到调整控件之间的间隔空间的目的。Box 容器提供了 4 种透明的组件,分别是 rigid area、strut、glue、filler。Box 容器分别提供了不同的方法来创建这些组件。这四个组件的特点如下:

  • Rigid area 是一种用户可以定义水平和垂直尺寸的透明组件;
  • strut 与 rigid area 类似,但是用户只能定义一个方向的尺寸,即水平方向或者垂直方向,不能同时定义水平和垂直尺寸;
  • 当用户将 glue 放在两个控件之间时,它会尽可能的占据两个控件之间的多余空间,从而将两个控件挤到两边;
  • Filler 是 Box 的内部类,它与 rigid area 相似,都可以指定水平或者垂直的尺寸,但是它可以设置最小,最大和优先尺寸。

用 BoxLayout 进行布局

在了解了 BoxLayout 和 Box 容器的基本特点后,我们来看一下 BoxLayout 的优点,首先 BoxLayout 可以进行对控件进行垂直或者水平布局,同时 BoxLayout 使用起来较为简单,然而把它和 Box 容器相结合,就可以进行较为复杂的布局,达到同使用 GridBagLayout 的一样的效果,但是使用起来要简单方便多了。我们用按钮的布局作为例子来看怎样运用 BoxLayout 和 Box 容器进行布局:

图 1. 应用 BoxLayout 进行按钮布局例子 1

我们在布局中经常会碰到如图 1 所示要把按钮放在容器的两端,那么我们就可以给容器定义一个 BoxLayout 来布局按钮,我们在按钮 1 和按钮 2 之间放置一个不可见的 glue,如前面所提到的那样,glue 就会尽量挤占掉两个按钮之间的空间,从而将两个按钮放在两端。

图 2. 应用 BoxLayout 进行按钮布局例子 2

再来看图 2 的例子,我们经常会遇到要将两个按钮放在容器的右边,我们就可以给容器定义一个 BoxLayout, 先放一个不可见的 glue,这个 glue 会挤占左边的空间,从而将两个按钮推到右边,

在两个按钮之间再放一个 strut,它也是不可见的,它会把两个按钮分隔开。

BoxLayout 布局实例

在基于前面讨论的基础上,我们现在来看一个具体的运用例子,假设图 3 是我们需要完成的用户界面:

图 3. BoxLayout 演示

这个演示是一个虚拟的用户对话框,只用于演示如何使用 BoxLayout, 例子代码中没有实现控件的动作。我们假定通过它用户可以选择要查询的运动会项目,然后查询,对话框中的表格显示了查询到的运动会项目的报名情况。为了完成这个布局,我们从上到下分别定义了 3 个 Panel, 分别叫做 topPanel,middlePanel,bottomPanel,这 3 个 Panel 都使用 BoxLayout。我们先看最上边的 topPanel,也就是包含表格的 Panel,topPanel 布局的基本思路是该 Panel 采用 BoxLayout 的垂直排列布局,先放置一个不可见的 Strut, 使topPanel 相 对顶部留出一定的空间,再放置包含表格的滚动窗格,再加入一个不可见的Strut,从而使topPanelmiddlePanel之间留出一定的空间。TopPanel 的代码如清单 1 所示:

清单 1. topPanel 示例代码清单
  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 所示。

清单 2. middlePanel 示例代码清单
  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 所示。

清单 3. bottomPanel 示例代码清单
  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。

清单 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. }

运用 BoxLayout 进行 Swing 控件布局的更多相关文章

  1. CSharpGL(26)在opengl中实现控件布局/渲染文字

    CSharpGL(26)在opengl中实现控件布局/渲染文字 效果图 如图所示,可以将文字.坐标轴固定在窗口的一角. 下载 CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入( ...

  2. java笔记--使用事件分配线程更新Swing控件

    使用事件分配线程更新Swing控件: Swing并不是线程安全的,如果在多个线程中更新Swing控件,则很可能造成程序崩溃. 为了避免这种问题,可以使用时间分配线程来更新Swing控件. EventQ ...

  3. React-Native 之控件布局

    Nodejs 一度将前端JS 推到了服务器端,而15年FB的React-Native RN再一次将JS 推到了移动端的开发浪潮中.RN的优势这里不再重复,它是我们这些习惯了服务端.web端开发,而又不 ...

  4. 学习笔记<4>初步控件布局

    一.控件布局基本概念 指控制控件在Activity当中的位置.大小.颜色以及其他控件样式属性 二.控件布局两种方法 1.使用布局文件完成控件布局(eclipse可视化拖拽控件实现) 2.在JAVA代码 ...

  5. 利用wtl的CDialogResize自动调整atl ActiveX控件布局

    前言 利用atl 开发activex控件时,如果使用atl复合控件时,acitvex控件上的界面元素不会自动改变大小,如果自己在OnSize中处理每个子控件的布局是一件非常麻烦的事,我们可以借助wtl ...

  6. QT学习记录之控件布局

    作者:朱金灿 来源:http://blog.csdn.net/clever101 想到控件布局就会想到Windows编程中要实现对话框上的控件的合理布局是一件多么艰难的事情.对此QT提出了一个很方便的 ...

  7. CPF 入门教程 - 控件布局(六)

    CPF netcore跨平台桌面UI框架 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) CPF 入门教程 - 样式和动画(三) CPF 入门教程 - 绘图(四) C ...

  8. 图书管理系统总结——JAVA Swing控件简介

    断断续续学习JAVA语言,写了一个多月数据库大作业,终于在五一过后写完了.由于第一次使用JAVA和数据库,遇到了许多问题,记录下来,以备以后查看. 我使用的JAVA SE,说实话,在开发后期,觉得JA ...

  9. Android入门(六):Android控件布局属性全解

    第一类:属性值为true或falseandroid:layout_centerHrizontal 水平居中 (Hrizontal表示水平)android:layout_centerVertical 垂 ...

随机推荐

  1. 【LeetCode练习题】Valid Palindrome

    Valid Palindrome Given a string, determine if it is a palindrome, considering only alphanumeric char ...

  2. Hive 3、Hive 的安装配置(本地derby模式)

    这种方式是最简单的存储方式,只需要在hive-site.xml做如下配置便可; $ vim hive-site.xml <configuration>   <property> ...

  3. UITableView使用总结和性能优化

    UITableView使用总结和性能优化    UITableView有两种风格:UITableViewStylePlain和UITableViewStyleGrouped.如 果我们查看UITabl ...

  4. handsontable插件HOOK事件

    Hook插件 afterChange (changes: Array, source: String):1个或多个单元格的值被改变后调用     changes:是一个2维数组包含row,prop,o ...

  5. 学习Android之SharedPreferences使用

    效果图例如以下: 当我们想让自己的属性设置保存下来,这时就须要SharedPreferences. 上面这个小程序,音乐状态是保存下来的.使用的上一次退出的状态. 进入DDMS,data文件下的dat ...

  6. nodejs之简介及安装(一)

    @[nodejs|个人学习笔记] nodejs简介 什么是node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. 参考网站 一.nodejs.cn 二 ...

  7. Webstrom 使用过程中遇到的问题以及解决方案

    作为一个前端开发,我用过webstorm和sublime两个编辑器.sublime小巧轻便,不耗内存.但是webstorm具有以下特点,让我难以舍弃. webstorm优点 点击一个函数名,它会跳到函 ...

  8. JSP基础学习(二)

    1.JSP页面的内容组成 静态部分:标准的HTML标签.静态的页面内容,这些内容与静态的HTML页面相同 动态部分:这些由java程序来动态生成 2.<% out.println(new jav ...

  9. 使用oracle来计算方差及标准差

    /* Formatted on 5/24/2012 4:15:58 PM (QP5 v5.149.1003.31008) */ SELECT deptno,       ename,          ...

  10. javaScript动态添加样式

    [动态添加css样式] <html> <head> <script type="text/javascript"> window.onload= ...