java布局_运用 BoxLayout 进行 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 实例的例子:

JPanel panel=new JPanel();

BoxLayout layout=new BoxLayout(panel, BoxLayout.X_AXIS);

panel.setLayout(layoout);Show moreShow more icon

在这个例子中,一个 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

image003.jpg

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

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

82c12f2f349468b11db76b585b91d737.png

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

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

BoxLayout 布局实例

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

图 3. BoxLayout 演示

8cbcd33746f7132f7cafdfed685f708f.png

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

清单 1. topPanel 示例代码清单

static void createTopPanel() {

topPanel = new JPanel();

String[] columnName = { "姓名", "性别", "单位", "参加项目", "备注" };

String[][] rowData = { { "张三", "男", "计算机系", "100 米 ,200 米", "" },

{ "李四", "男", "化学系", "100 米,铅球", "" },

};

// 创建表格

JTable table = new JTable(new DefaultTableModel(rowData, columnName));

// 创建包含表格的滚动窗格

JScrollPane scrollPane = new JScrollPane(table);

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

// 定义 topPanel 的布局为 BoxLayout,BoxLayout 为垂直排列

topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));

// 先加入一个不可见的 Strut,从而使 topPanel 对顶部留出一定的空间

topPanel.add(Box.createVerticalStrut(10));

// 加入包含表格的滚动窗格

topPanel.add(scrollPane);

// 再加入一个不可见的 Strut,从而使 topPanel 和 middlePanel 之间留出一定的空间

topPanel.add(Box.createVerticalStrut(10));

}Show moreShow more icon

位于中间的 middlePanel 比较复杂些,它的左边包括标签运动会项目和运动会项目列表,中间是两个按钮,我们假定点击 >> 按钮将会把用户在运动会项目列表中选中的项目移到右边的查询项目列表,点击 << 按钮则将右边查询项目列表中选中的项目移回到左边的运动会项目列表。它的布局的基本思路是定义了三个子 Panel,这三个子 Panel 分别对应最左边的标签和运动会项目列表,中间的两个按钮,和最右边的标签和查询项目列表,最左边的 Panel 采用 BoxLayout 的水平排列布局,中间的 Panel 采用 BoxLayout 的垂直排列布局,两个按钮之间加入一个不可见的 rigidArea,调整两个按钮之间的垂直距离,最右边的 Panel 采用 BoxLayout 的水平排列布局放置标签和查询项目列表。然后采用水平排列布局的 middlePanel 将三个 Panel 依次水平的加入。 MiddlePanel 的代码如清单 2 所示。

清单 2. middlePanel 示例代码清单

static void createMiddlePanel() {

// 创建 middlePanel

middlePanel = new JPanel();

// 采用水平布局

middlePanel .setLayout(new BoxLayout(middlePanel,BoxLayout.X_AXIS ));

// 创建标签运动会项目

JLabel sourceLabel = new JLabel("运动会项目:");

sourceLabel.setAlignmentY(Component.TOP_ALIGNMENT );

sourceLabel.setBorder(BorderFactory.createEmptyBorder (4, 5, 0, 5));

// 创建列表运动会项目

DefaultListModel listModel = new DefaultListModel();

listModel.addElement("100 米");

listModel.addElement("200 米");

listModel.addElement("400 米");

listModel.addElement("跳远");

listModel.addElement("跳高");

listModel.addElement("铅球");

JList sourceList = new JList(listModel);

sourceList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );

sourceList.setVisibleRowCount(5);

JScrollPane sourceListScroller = new JScrollPane(sourceList);

sourceListScroller.setPreferredSize(new Dimension(120, 80));

sourceListScroller

.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );

sourceListScroller.setAlignmentY(Component.TOP_ALIGNMENT );

// 创建最左边的 Panel

JPanel sourceListPanel = new JPanel();

// 最左边的 Panel 采用水平布局

sourceListPanel.setLayout(new BoxLayout(sourceListPanel,

BoxLayout.X_AXIS ));

// 加入标签到最左边的 Panel

sourceListPanel.add(sourceLabel);

// 加入列表运动会项目到最左边的 Panel

sourceListPanel.add(sourceListScroller);

sourceListPanel.setAlignmentY(Component.TOP_ALIGNMENT );

sourceListPanel.setBorder(BorderFactory.createEmptyBorder (0, 0, 0, 30));

// 将最左边的 Panel 加入到 middlePanel

middlePanel .add(sourceListPanel);

// 定义中间的两个按钮

JButton toTargetButton = new JButton(">>");

JButton toSourceButton = new JButton("<

// 定义中间的 Panel

JPanel buttonPanel = new JPanel();

// 中间的 Panel 采用水平布局

buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS ));

// 将按钮 >> 加入到中间的 Panel

buttonPanel.add(toTargetButton);

//两个按钮之间加入一个不可见的 rigidArea

buttonPanel.add(Box.createRigidArea (new Dimension(15, 15)));

// 将按钮 << 加入到中间的 Panel

buttonPanel.add(toSourceButton);

buttonPanel.setAlignmentY(Component.TOP_ALIGNMENT );

buttonPanel.setBorder(BorderFactory.createEmptyBorder (15, 5, 15, 5));

// 将中间的 Panel 加入到 middlePanel

middlePanel .add(buttonPanel);

// 创建标签查询项目

JLabel targetLabel = new JLabel("查询项目:");

targetLabel.setAlignmentY(Component.TOP_ALIGNMENT );

targetLabel.setBorder(BorderFactory.createEmptyBorder (4, 5, 0, 5));

// 创建列表查询项目

DefaultListModel targetListModel = new DefaultListModel();

targetListModel.addElement("100 米");

JList targetList = new JList(targetListModel);

targetList

.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );

targetList.setVisibleRowCount(5);

JScrollPane targetListScroller = new JScrollPane(targetList);

targetListScroller.setPreferredSize(new Dimension(120, 80));

targetListScroller

.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );

targetListScroller.setAlignmentY(Component.TOP_ALIGNMENT );

// 创建最右边的 Panel

JPanel targetListPanel = new JPanel();

// 设置最右边的 Panel 为水平布局

targetListPanel.setLayout(new BoxLayout(targetListPanel,

BoxLayout.X_AXIS ));

// 将标签查询项目加到最右边的 Panel

targetListPanel.add(targetLabel);

// 将列表查询项目加到最右边的 Panel

targetListPanel.add(targetListScroller);

targetListPanel.setAlignmentY(Component.TOP_ALIGNMENT );

targetListPanel.setBorder(BorderFactory.createEmptyBorder (0, 30, 0, 0));

// 最后将最右边的 Panel 加入到 middlePanel

middlePanel .add(targetListPanel);

}Show moreShow more icon

我们最后来看一下 bottomPanel 如何布局,bottomPanel 包括分布在两边的两个按钮,其实 bottomPanel 的布局和章节用 BoxLayout 进行布局中的图 1 是一致的,我们在两个按钮之间加入一个 glue, 这个 glue 会挤占两个按钮之间的空间,从而将两个按钮布局到两边,在 bottemPanel 中用一个 buttonPanel 来放置这两个按钮。BottomPanel 采用 BoxLayout, 首先放入一个 strut, 从而使 bottomPanel 和 middlePanel 之间留出距离,再放入 buttonPanel,再放入一个 strut, 从而使 bottomPanel 和底部之间留出距离,BottomPanel 的代码如清单 3 所示。

清单 3. bottomPanel 示例代码清单

static void createBottomPanel() {

// 创建查询按钮

JButton actionButton = new JButton("查询");

// 创建退出按钮

JButton closeButton = new JButton("退出");

// 创建 bottomPanel

bottomPanel = new JPanel();

// 设置 bottomPanel 为垂直布局

bottomPanel .setLayout(new BoxLayout(bottomPanel,BoxLayout.Y_AXIS ));

// 创建包含两个按钮的 buttonPanel

JPanel buttonPanel = new JPanel();

// 设置 bottomPanel 为水平布局

buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS ));

// 将查询按钮加入到 buttonPanel

buttonPanel.add(actionButton);

//加入一个 glue, glue 会挤占两个按钮之间的空间

buttonPanel.add(Box.createHorizontalGlue ());

// 将退出按钮加入到 buttonPanel

buttonPanel.add(closeButton);

// 加入一个 Strut,从而使 bottomPanel 和 middlePanel 上下之间留出距离

bottomPanel .add(Box.createVerticalStrut (10));

// 加入 buttonPanel

bottomPanel .add(buttonPanel);

// 加入一个 Strut,从而使 bottomPanel 和底部之间留出距离

bottomPanel .add(Box.createVerticalStrut (10));

}Show moreShow more icon

我们用一个 Panel 来从上到下放置 topPanel、middlePanel 和 bottomPanel,这个 Panel 采用了 GridBagLayout, 最后我们将这个 Panel 加到一个窗体中去,请参考清单 4。

清单 4. 创建窗体示例代码清单

public static void main(String[] args) {

// 创建 topPanel

createTopPanel ();

// 创建 middlePanel

createMiddlePanel ();

// 创建 bottomPanel

createBottomPanel ();

// 创建包含 topPanel,middlePanel 和 bottomPanel 的 panelContainer

JPanel panelContainer = new Jpanel();

//panelContainer 的布局为 GridBagLayout

panelContainer.setLayout(new GridBagLayout());

GridBagConstraints c1 = new GridBagConstraints();

c1.gridx = 0;

c1.gridy = 0;

c1.weightx = 1.0;

c1.weighty = 1.0;

c1.fill = GridBagConstraints.BOTH ;

// 加入 topPanel

panelContainer.add(topPanel,c1);

GridBagConstraints c2 = new GridBagConstraints();

c2.gridx = 0;

c2.gridy = 1;

c2.weightx = 1.0;

c2.weighty = 0;

c2.fill = GridBagConstraints.HORIZONTAL ;

// 加入 middlePanel

panelContainer.add(middlePanel,c2);

GridBagConstraints c3 = new GridBagConstraints();

c3.gridx = 0;

c3.gridy = 2;

c3.weightx = 1.0;

c3.weighty = 0;

c3.fill = GridBagConstraints.HORIZONTAL ;

// 加入 bottomPanel

panelContainer.add(bottomPanel,c3);

// 创建窗体

JFrame frame = new JFrame("Boxlayout 演示");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );

panelContainer.setOpaque(true);

frame.setSize(new Dimension(480, 320));

frame.setContentPane(panelContainer);

frame.setVisible(true);

}Show moreShow more icon

本文的例子是在文件 BoxLayoutDemo.zip 中,您将其展开,导入到 Eclipse 中去,就可运行例子。

结束语

您通过本文的介绍,可以对 BoxLayout 这个布局管理器如何进行布局能够有一定的了解,也可以在自己的实践过程中进一步总结出自己的方法。

Download

相关主题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js变量类型

js中有null和undefined&#xff0c;null是指对象不存在&#xff0c;undefined是指原生数据不存在 var h {name:lisi,age:28};console.log(h.name)//对象用的是点语法&#xff0c;php中是name->lisi 下面是数组&#xff0c;数组用的是【】语法 1 var arr [a,3,hello,true];…

OPENCV MFC 程序出错修改

error C2146: 语法错误 : 缺少“;”(在标识符“PVOID64”的前面) 来源:http://houjixin.blog.163.com/blog/static/356284102009112395049370/ DirectShow 2009-12-23 09:50:49 阅读311 评论0 字号&#xff1a;大中小打开winnt.h文件&#xff0c;发现问题就是在winnt.h头文件中…

测试人员报BUG的正确姿势

每次我提需求的时候&#xff0c;都会和开发一言不合就上BUG。曾经看到一个段子&#xff0c;告诉了我&#xff0c;吵架是不行滴&#xff01;影响心情&#xff0c;正确报bug的姿势应该是这样&#xff1a;不要对程序员说&#xff0c;你的代码有BUG。他的第一反应是&#xff1a;1、…

java链表实现_链表的原理及java实现

一&#xff1a;单向链表基本介绍链表是一种数据结构&#xff0c;和数组同级。比如&#xff0c;Java中我们使用的ArrayList&#xff0c;其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高&#xff0c;但是插入和删除时优势明显。下面对单向链表…

python和django中的常见错误

int() argument must be a string or a number, not tupleError in formatting: coercing to Unicode: need string or buffer, int foundData truncated for column content at row 1sql语句中单引号的设置字段类型字段长度 ascii codec cant decode byte 0xe7 in position 0:…

20141126-解决联网问题-笔记

当你的网络出现故障或无法连通时&#xff0c;如何才能简单高效的找出故障&#xff1f;其实只需要一个ping命令&#xff0c;就可以判断TCP/IP协议故障…… 1、Ping 127.0.0.1&#xff1a; 127.0.0.1是本地循环地址&#xff0c;如果本地址无法Ping通&#xff0c;则表明本地机TCP/…

inittab脚本启动解析 (zz)

http://blog.chinaunix.net/uid-17188120-id-4073497.html 1&#xff0c;启动inittab第一步&#xff1a;启动内核第二步&#xff1a;执行init &#xff08;配置文件/etc/inittab&#xff09;第三步&#xff1a;启动相应的脚本&#xff0c;执行inittab脚本&#xff0c;并且执行其…

java缓存技术_java缓存技术

最近在做java缓存,了解了一下.以下仅是对map对方式讨论。没有对点阵图阵讨论。作缓存要做以下2点:1:清理及更新缓存时机的处理:. 虚拟机内存不足,清理缓存.. 缓存时间超时,或访问次数超出, 启动线程更新2:类和方法的反射 (线程嵌套调用)reflect.invoke的使用。代码如下&#xf…

xss challenge 解题思路(1-3)

challenge1: 用很基本的方法即可&#xff0c;截图如下&#xff1a; 提交后成功弹窗&#xff0c;完成。 challenge2 这次我们发现我们输入的内容被放入value”“ 中&#xff0c;所以需要将前面的结构闭合&#xff0c;构造如下&#xff1a; "><script>alert(docume…

宾得准饼干广角镜头DA15

DA15的挂机效果图&#xff0c;感觉还是超级的小&#xff0c;是最小的广角镜头了&#xff1a; 主要特点1. 超广视角当安装在宾得数码单反相机上时&#xff0c;这款全新的镜头提供相当于35mm胶片规格的约23mm画面视角&#xff0c;可使拍摄者拍摄出独特的诱人影像和超广角镜头独有…

无限“递归”的python程序

如果一个函数直接或者间接调用了自己&#xff0c;那么就形成了递归&#xff08;recursion&#xff09;&#xff0c;比如斐波那契数列的一个实现 def fib(n):if n < 2:return 1else:return fib(n - 1) fib(n - 2) 递归一定要有结束条件&#xff0c;否则就形成了死循环&#…

java slf4j_SLF4J 使用手册

原文链接 译者&#xff1a;zivyuJava的简单日志门面( Simple Logging Facade for Java SLF4J)作为一个简单的门面或抽象&#xff0c;用来服务于各种各样的日志框架&#xff0c;比如java.util.logging、logback和log4j。SLF4J允许最终用户在部署时集成自己想要的日志框架。需要…

[译]Java 垃圾回收介绍

说明&#xff1a;这篇文章来翻译来自于Javapapers 的Java Garbage Collection Introduction 在Java中&#xff0c;对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的。和C语言不一样的是&#xff0c;开发中不需要在Java中写垃圾回收代码。这也是使Java更加流行而且帮…

打印三角形

直角三角形 #include<iostream> using namespace std; int main() { int i,j; for(i1;i<10;i) {for(j1;j<i;j) cout<<"*"; cout<<endl; } } ———————————————————————————…

Linux基础入门学习笔记之二

第三节 用户及文件权限管理 Linux用户管理 Linux是可以实现多用户登录的操作系统 查看用户who命令用于查看用户 shiyanlou是当前登录用户的用户名 pts/0中pts表示伪终端&#xff0c;后面的数字表示伪终端的序号。 后面是当前伪终端启动时间 创建用户创建用户需要root权限&#…

java选填_java基础填空选择题

Core Java试题选择填空题&#xff1a;全部为多选题&#xff0c;只有全部正确才能得分。1. 编译java程序的命令是__B_;运行java程序的命令是____A____;产生java文挡的命令是_____D___;查询java类型是否是serializable类型的命令是___C_____;产生java安全策略文件的命令是____E__…

这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下...

这个TBlog已经全新改版了&#xff0c;更名为UUBlog 新版地址&#xff1a; 用Python和Django实现多用户博客系统——UUBlog 断断续续2周时间吧&#xff0c;用django做了一个多用户博客系统&#xff0c;现在还没有做完&#xff0c;做分享下,以后等完善了再慢慢说 做的时候房展了博…

Hibernate的generator属性

本文讲述Hibernate的generator属性的意义。Generator属性有7种class&#xff0c;本文简略描述了这7种class的意义和用法。[xhtml] view plaincopy <class name"onlyfun.caterpillar.User" table"USER"> <id name"id" type"stri…

java 对象池 博客_Java对象池技术的原理及其实现的小结

一起学习Java对象的生命周期大致包括三个阶段&#xff1a;对象的创建&#xff0c;对象的使用&#xff0c;对象的清除。因此&#xff0c;对象的生命周期长度可用如下的表达式表示&#xff1a;T T1 T2 T3。其中T1表示对象的创建时间&#xff0c;T2表示对象的使用时间&#xff0c…

matlab中gatbx工具箱的添加

1. 从http://crystalgate.shef.ac.uk/code/下载工具箱压缩包gatbx.zip 2. 解压gatbx.zip&#xff0c;将其子文件夹genetic放在matlab安装目录toolbox文件夹下 3. 在matlab主窗口选择File -> Set Path&#xff0c; 单击"Add Folder"按钮&#xff0c;找到工具箱所在…