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,一经查实,立即删除!

相关文章

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

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

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;可使拍摄者拍摄出独特的诱人影像和超广角镜头独有…

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权限&#…

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

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

MySQL数据高级查询之连接查询、联合查询、子查询

2019独角兽企业重金招聘Python工程师标准>>> 一、连接查询 连接查询: 将多张表(>2)进行记录的连接(按照某个指定的条件进行数据拼接)。 连接查询的意义: 在用户查看数据的时候,需要显示的数据来自多张表. 连接查询: join, 使用方式: 左表 join 右表&#xff1b;左…

Oracle11g解锁报错SP2-0306-选项无效

普通用户登录isqlplus: (一)在浏览器中输入URL &#xff08;http://localhost:5560/isqlplus&#xff09;。显示登录界面 这里只能用普通用户进行登录&#xff0c;因为要用sys登录&#xff0c;必须用sys的DBA身份登录。所以用普通用户SCOTT&#xff0c;但是还未解锁 问题:SP2-0…

Chrome浏览器无法观看视频,一直提示“adobe flash player 已过期” ?

很多新用户在安装了Chrome浏览器或者更新过的的时候&#xff0c;经常提示“ adobe flash player 已过期”的问题&#xff0c;反复提示&#xff0c;导致无法观看视频。于是从网上也找了很多办法都没有解决。这里给大家提供一个最完美的解决方案。经亲自测试&#xff0c;完美解决…

关于JVM的垃圾回收GC的一些记录

目录 一、JVM内存区域划分 二、从一个基本问题开始引入垃圾回收 三、GC作用的区域 三、如何确定一个对象是否可以被当成垃圾进行回收 &#xff08;1&#xff09;引用计数法 &#xff08;2&#xff09;可达性分析算法 &#xff08;3&#xff09;引用的类型 &#xff08;3…

codevs1219 骑士遍历(棋盘DP)

题目描述 Description设有一个n*m的棋盘&#xff08;2≤n≤50&#xff0c;2≤m≤50&#xff09;&#xff0c;如下图&#xff0c;在棋盘上有一个中国象棋马。 规定&#xff1a; 1)马只能走日字 2)马只能向右跳 问给定起点x1,y1和终点x2,y2&#xff0c;求出马从x1,y1出发到x2,y2的…

java ssh免密登录_SSH公钥、私钥配置(SSH免密码登录方式)

1.首先使用想要发起ssh免密访问的用户A登录Linux(简称客户端Linux)2.进入该用户的家目录(cd ~)&#xff0c;看是否有.ssh文件夹(linux中以.开头文件夹是隐藏的&#xff0c;使用ll -a进行查看)&#xff0c;如果没有则创建(mkdir ~/.ssh)&#xff0c;并修改访问权限(chmod 700 ~…

win8, VS2013 .NET 4.5在哪找svcutil.exe?

我这个纠结呀&#xff0c;公司用win8&#xff0c; .NET 4.5。想做一个很简单的项目&#xff0c;就是wcf宿主iis&#xff0c;项目根目录下有aspx文件和svc文件。于是参考了一个博客http://www.cnblogs.com/yjmyzz/archive/2008/08/19/1270961.html&#xff0c;[原创]WCF入门级使…

Starling 2D框架简介

本系列是对Introducing Starling pdf的翻译&#xff0c;下文是对adobe开发人员中心的一片日志的转载&#xff0c;地址为http://www.adobe.com/cn/devnet/flashplayer/articles/introducing_Starling.html Starling 是在 Stage3D APIs 基础上开发的一种 ActionScript 3 2D 框架&…

Android AutoCompleteTextView控件实现类似百度搜索提示,限制输入数字长度

Android AutoCompleteTextView 控件实现类似被搜索提示&#xff0c;效果如下 1.首先贴出布局代码 activity_main.xml&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res…

java即时聊天系统毕业_(完整版)基于Java即时聊天系统的设计与实现毕业论文设计...

目录1 前言...................................................................................................................................1.1 课题选题背景...................................................................................................…

java与算法_Java与算法之(1) - 冒泡排序

冒泡排序法的原理是&#xff0c;每次比较相邻的两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。例如对4 3 6 2 7 1 5这7个数字进行从小到大的排序&#xff0c;从最左侧开始&#xff0c;首先比较4和3因为是从小到大排序&#xff0c;4和3的顺序显然是错误的&#xff0…

JQuery链式操作简单的菜单列表

看到这个简单的菜单demo&#xff0c;也是为了再看看JQuery对DOM的操作&#xff0c;一直都记不牢&#xff0c;特别是siblings&#xff08;&#xff09;这个总是想不起来。 这次再过一遍JQuery&#xff0c;不管简单的还是复杂的demo 还是坚持练习一遍吧&#xff01;只为记录&…