当把组件添加到窗体上时,并不是直接把组件添加到JFrame对象上的,而是需要先获得窗体的内容面板,然后把组件添加到内容面板上。获得内容面板的方式是调用窗体的getContentPane()方法,该方法的返回值是Container类对象,它就表示了窗体的内容面板。
布局管理器能够设置内容面板上组件的排列方式,也就是说内容面板被设置了某种布局管理器之后就能实现组件按照特定规律排列。常用的布局管理有:流式布局管理器、边框布局管理器、卡片布局管理器、增强网格布局管理器等。本小节将详细讲解布局管理器的相关知识。
20.3.1流式布局管理器
Java语言用FlowLayout类来表示流式布局管理器。流式布局管理器所定义的组件排列方式有点像横版写字的方式,每个组件就相当于一个字。排列组件时是从左排到右还是从右排到左,是由组件所在容器的componentOrientation属性决定的。程序员可以通过setComponentOrientation()方法设置componentOrientation属性,也即设置组件的排列方式。setComponentOrientation()方法的参数一般可以用静态属性的方式进行设定,如果设定参数为ComponentOrientation.RIGHT_TO_LEFT,则表示组件从右向左排列,相应的,如果设置参数为ComponentOrientation.LEFT_TO_RIGHT,那么组件从左向右的方式排列。
除了可以设定组件的排列方向外,程序员还可以设定组件的对齐方式,也就是“左对齐”排列还是“右对齐”排列。设置对齐方式需要通过FlowLayout的构造方法参数进行设定,如果设置FlowLayout的构造方法参数为FlowLayout.LEFT,则组件以左对齐方式排列,如果设置参数为FlowLayout.RIGHT则组件以右对齐方式排列,设置参数为FlowLayout.CENTER时组件以局中方式对齐,局中对齐也是默认的对齐方式。
如果界面上组件较多,组件会自动换到下一行进行排列。界面上的组件还可以设置相互的距离,这样的设置也要通过FlowLayout的构造方法实现,程序员可以用如下的方式设置组件间的距离。
new FlowLayout(FlowLayout.RIGHT,100,30);
以上语句创建了一个流式布局管理器对象,并设置组件右对齐排列,组件之间横向距离为100像素,纵向距离为30像素。
在实际开发过程中,往往并不是直接创建一个JFrame类的对象来表示窗体,而是定义一个JFrame类的子类,在这个子类中把各种组件都定义成子类的属性,这样的方式能够很好的提高组件的安全性,保证组件不被窗体之外的其他代码随意访问。下面的【例20_02】展示了流式布局管理器的效果。
【例20_02 流式布局管理器】
Exam20_02.java
import javax.swing.*;
import java.awt.*;
//Exam20_02Frame是JFrame的子类,表示一个窗体
class Exam20_02Frame extends JFrame{
JButton button1;//按钮1
JButton button2;//按钮2
JButton button3;//按钮3
public Exam20_02Frame(){
init();
}
//init()方法负责初始化窗体
private void init(){
button1 = new JButton("按钮1");//初始化按钮1
button2 = new JButton("按钮2");//初始化按钮2
button3 = new JButton("按钮3");//初始化按钮2
Container container = this.getContentPane();//获得窗体的内容面板
//设置组件右对齐,并且横向间隔20像素,纵向间隔30像素
container.setLayout(new FlowLayout(FlowLayout.RIGHT,20,30));
//设置组件从左向右排列
container.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
container.add(button1);
container.add(button2);
container.add(button3);
}
}
public class Exam20_02 {
public static void main(String[] args) {
Exam20_02Frame frame = new Exam20_02Frame();
frame.setSize(400, 200);//设置窗体的大小
frame.setLocationRelativeTo(null);//设置窗体出现在屏幕正中间
frame.setTitle("Exam20_02Frame");//设置窗体的标题
//设置关闭窗体时同时停止程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);//设置窗体可见
}
}
【例20_02】的运行结果如图20-2所示。
图20-2【例20_02】运行结果
20.3.2边框布局管理器
表示边框布局管理器的类是BorderLayout,如果给内容面板设置了边框布局管理器,内容面板就会被划分成东、南、西、北、中五个区域,在内容面板中,以“上北下南,左西右东”的方式布局各个区域的位置。每个位置都用特定的静态属性来表示,下面的表20-2展示了各个区域对应的静态属性。
表20-2边框布局管理器中表示各区域的静态属性
静态属性 | 表示区域 |
---|---|
BorderLayout.EAST | 东 |
BorderLayout.SOUTH | 南 |
BorderLayout.WEST | 西 |
BorderLayout.NORTH | 北 |
BorderLayout.CENTER | 中 |
程序员在使用add()方法向内容面板上添加组件的时候指定添加哪一个组件以及组件被添加到哪一个区域。在给中间区域放置了组件之后,如果东南西北这四个区域有空缺,那么中间区域的这个组件会占据这些空缺区域。假如没有指定组件放在哪个区域,在这种情况下组件会默认被放置到中间区域。需要注意:内容面板上的每个区域都只能放一个组件,如果把两个或两个以上的组件同时放到一个区域的时候,后添加到这个区域的组件会把之前添加到这个区域的组件覆盖掉。
程序员除了可以设置组件的位置之外,还可以设置各组件的之间的间隔距离,这个间隔距离也是在BorderLayout的构造方法中设置的。下面的【例20_03】展示了边框布局管理器的效果。
【例20_03 边框布局管理器】
Exam20_03.java
import javax.swing.*;
import java.awt.*;
class Exam20_03Frame extends JFrame{
JButton button1;
JButton button2;
JButton button3;
JButton button4;
JButton button5;
public Exam20_03Frame(){
init( );
}
private void init( ){
button1 = new JButton("东");
button2 = new JButton("南");
button3 = new JButton("西");
button4 = new JButton("北");
button5 = new JButton("中");
Container container = this.getContentPane();
//设置边框布局管理器,并设置组件横向间隔5像素纵向间隔10像素
container.setLayout(new BorderLayout(5,10));
container.add(button1,BorderLayout.EAST);
container.add(button2,BorderLayout.SOUTH);
container.add(button3,BorderLayout.WEST);
container.add(button4,BorderLayout.NORTH);
container.add(button5,BorderLayout.CENTER);
}
}
public class Exam20_03 {
public static void main(String[] args) {
Exam20_03Frame frame = new Exam20_03Frame();
frame.setSize(400, 300);//设置窗体的大小
frame.setLocationRelativeTo(null);//设置窗体出现在屏幕正中间
frame.setTitle("Exam20_03Frame");//设置窗体的标题
//设置关闭窗体时同时停止程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);//设置窗体可见
}
}
【例20_03】的运行结果如图20-3所示。
图20-3【例20_03】运行结果
从图20-3可以看出:使用边框布局管理器时,组件会出现在指定的区域中。
20.3.3网格布局管理器
表示网格布局管理器的类是GridLayout,它的布局方式是把整个内容面板看成是一个N行M列的二维网格阵列,桌面上的每个组件都占据一个网格,这些网格的大小是均匀的。在创建GridLayout类对象时,如果没有指定N和M的值,那么所有组件将自动排除一行并均匀的占满整个窗体界面。反之,如果在创建GridLayout对象时指定了N和M的值,则组件会排列为N行M列。当组件的数量多于网格数量时,内容面板会增加列来显示多余的组件,但行的数量不会增加。而当组件的数量少于网格数量时,内容面板会优先保证行的数量足够。例如:一个4×4的网格矩阵中如果只有4个按钮,那么这4个按钮会排成纵向的一列以保证“凑够”4行,而不是横向排列以保证“凑够”4列。在默认情况下,网格布局下的组件都是“紧挨”在一起的,如果希望各组件之间有一定的间距,也可以通过构造方法参数进行设置,例如:
new GridLayout(2,2,10,5);
这条语句创建了一个2×2的网格矩阵,并且规定组件横向间距10像素,纵向间距5像素。下面的【例20_04】展示了网格布局管理器的效果。
【例20_04 网格布局管理器】
Exam20_04.java
import java.awt.*;
import javax.swing.*;
class Exam20_04Frame extends JFrame{
JButton button1;
JButton button2;
JButton button3;
JButton button4;
public Exam20_04Frame( ){
init( );
}
private void init( ){
button1 = new JButton("按钮1");
button2 = new JButton("按钮2");
button3 = new JButton("按钮3");
button4 = new JButton("按钮4");
Container container = this.getContentPane();
//设置内容面板布局为2×2网格,组件横向间距10像素纵向间距5像素
container.setLayout(new GridLayout(2,2,10,5));
container.add(button1);
container.add(button2);
container.add(button3);
container.add(button4);
}
}
public class Exam20_04 {
public static void main(String[] args) {
Exam20_04Frame frame = new Exam20_04Frame();
frame.setSize(400, 300);//设置窗体的大小
frame.setLocationRelativeTo(null);//设置窗体出现在屏幕正中间
frame.setTitle("Exam20_04Frame");//设置窗体的标题
//设置关闭窗体时同时停止程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);//设置窗体可见
}
}
【例20_04】的运行结果如图20-4所示。
图20-4【例20_04】运行结果
20.3.4空布局
前面几个小节中所讲解的布局管理器都会使组件以一定的方式排列。如果希望不受任何限制,完全按照自己的意愿排列组件,就可以不用任何布局管理器,这种布局方式被称为“空布局”。设置内容面板为空布局时,只需要把setLayout()方法的参数设置为null即可。使用空布局的方式排列组件,程序员可以自由设定组件的位置和大小。在Swing体系中,窗体的左上角是坐标系的原点,x轴向右延伸,y轴向下延伸。任何和一个组件都以组件左上角顶点位置作为这个组件在整个坐标系的位置。此外,Swing体系中的所有组件都被设计为矩形,因此只需要指定组件的宽度和高度就能定义出组件的大小。所有组件都以setLocation()定义位置,这个方法有两个参数,分别表示了组件的x坐标和y坐标。而所有的组件都以setSize()方法定义大小,这个方法也有两个参数,分别是组件的宽度和高度。组件的位置以及大小都是以像素为单位。下面的【例20_05】展示了以空布局方式排列组件的效果。
【例20_05 空布局】
Exam20_05.java
import java.awt.*;
import javax.swing.*;
class Exam20_05Frame extends JFrame{
JButton button1;
JButton button2;
public Exam20_05Frame( ){
init();
}
private void init( ){
button1 = new JButton("按钮1");
button2 = new JButton("按钮2");
Container container = this.getContentPane();
//把内容面板设置为空布局
container.setLayout(null);
//设置button1的位置为(0,0)
button1.setLocation(0, 0);
//设置button1的大小为200,100
button1.setSize(200, 100);
//设置button2的位置为(240,50)
button2.setLocation(240, 50);
//设置button2的大小为100,200
button2.setSize(100, 200);
container.add(button1);
container.add(button2);
}
}
public class Exam20_05 {
public static void main(String[] args) {
Exam20_05Frame frame = new Exam20_05Frame();
frame.setSize(400, 300);//设置窗体的大小
frame.setLocationRelativeTo(null);//设置窗体出现在屏幕正中间
frame.setTitle("Exam20_05Frame");//设置窗体的标题
//设置关闭窗体时同时停止程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);//设置窗体可见
}
}
【例20_05】的运行结果如图20-5所示。
图20-5【例20_05】运行结果