JavaGUI(一)——布局
AWT编程
AWT简介
当JDK1.0发布时,Sun公司提供了一套基本的GUI类库,这个GUI类库希望可以在所有平台下都能运行,这套基本类库被称为“抽象窗口工具集(Abstract Window Toolkit)”,它为Java应用程序提供了基本的图形组件。AWT是窗口框架,它从不同平台的窗口系统中抽取出共同组件,当程序运行时,将这些组件的创建和动作委托给程序所在的平台。简而言之,当AWT编写图形界面应用时,程序仅指定了界面组件的位置和行为,并未提供真正的实现,JVM调用操作系统本地图形界面来创建和平台一致的对等体。
使用AWT创建的图形界面应用和所在的运行平台有相同的界面风格,比如在Windows操作系统上,它表现出Windows风格;在UNIX操作系统上,它就表现出UNIX风格,Sun希望采用这种方式来实现“Write Once,Run Anywhere”的目标。
AWT继承体系
所有和AWT编程相关的类都放在java.awt包以及它的子包中,AWT编程中有两个基类:Component和MenuComponent。
- Component:代表一个能以图形化方式显示出来,并可与用户交互对象,例如Button代表一个按钮,TextField代表一个文本框等;
- MenuComponent:则代表图形界面的菜单组件,包括MenuBar(菜单条)。MenuItem(菜单项)等子类。
其中Container是一种特殊的Component,它代表一种容器,可以盛装普通的Component。
AWT中还有一个非常重要的接口叫LayoutManager,如果一个容器中有多个组件,那么容器就需要使用LayoutManager来管理这些组件的布局方式。
Comtainer继承体系
- Window是可以独立存在的顶级窗口,默认使用BorderLayout管理其内部组件布局;
- Panel可以容纳其他组件,但不能独立存在,它必须内嵌其他容器中使用,默认使用FlowLayout管理其内部组件布局;
- ScrollPane是一个带滚动条的容器,它也不能独立存在,默认使用BorderLayout管理其内部组件布局;
常见API
Component作为基类,提供了如下常用的方法来设置组件的大小、位置、可见性等。
方法签名 | 方法功能 |
---|---|
setLocation(int x,int y) | 设置组件的位置 |
setSize(int width,int height) | 设置组件的大小。 |
setBounds(int x, int y , int width, int height) | 同时设置组件的位置、大小 |
setVisible(Boolean b) | 设置该组件的可见性 |
Container作为容器根类,提供了如下方法来访问容器中的组件
方法签名 | 方法功能 |
---|---|
Component add(Component comp); | 向容器中添加其他组件(该组件既可以是普通组件,也可以是容器),并返回被添加的组件。 |
Component getComponentAt(int x,int y); | 返回指定点的组件。 |
int getComponentCount(); | 返回该容器内组件的数量。 |
Component[] getComponents(); | 返回该容器内的所有组件。 |
LayoutMannager布局管理器
之前,我们学习了Component中有一个方法setBounds()可以设置当前容器的位置和大小,但是我们需要明确一件事,如果我们手动地位组件设置位置和大小的话,就会造成程序的不通用性,例如:
Label label = new Label("HelloWorld!");
创建了一个label组件,很多情况下,我们需要让label组件的宽高和“HelloWorld!”这个字符串自身的宽高一致,这种大小称为最佳大小。由于操作系统存在差异,例如在windows上,我们要达到这样的效果,需要把该Label组件的宽和高设置为100px,20px,但是在Linux操作系统上,可能需要把Label组件的宽和高分别设置为120px,24px,才能达到同样的效果。
如果要让我们的程序在不同的操作系统下,都有相同的使用体验,那么手动设置组件的位置和大小,无疑是一种灾难,因为有太多的组件,需要分别设置不同操作系统下的大小和位置。为了解决这个问题,java提供了LayoutManager布局管理器,可以根据运行平台来自动调整组件大小,程序员不同再手动设置组件的大小和位置了,只需要为容器选择合适的布局管理器即可。
FlowLayout
在FlowLayout布局管理器中,组件像水流一样向某方向流动(排列),遇到障碍(边界)就折回,重头开始排列。在默认情况下,FlowLayout布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。
构造方法 | 方法功能 |
---|---|
FlowLayout() | 使用默认的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
FlowLayout(int align) | 使用指定的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
FlowLayout(int align,int hgap,int vgap) | 使用指定的对齐方式及指定的垂直间距、水平间距创建FLowLayout布局管理器。 |
FlowLayout中组件的排列方向从左向右、从右向左、从中间向两边等),该参数应该使用FlowLayout类的静态常量:FlowLayout.LEFT、FlowLayout.CENTER、FlowLayout.RIGHT,默认是左对齐。
FlowLayout中组件中间通过整数设置,单位是像素,默认是5个像素。
BorderLayout
BorderLayout将容器分为EAST、SOUTH、WEST、NORTH、CENTER五个区域,普通组件可以被放置在这5个区域的任意一个中。
当改变使用BorderLayout的容器大小时,NORTH、SOUTH和CENTER区域水平调整,而EAST、WEST和CENTER区域垂直调整。使用BorderLayout有如下两个注意点:
- 当向使用BorderLayout布局管理器的容器中添加组件时,需要指定要添加到哪个区域中。如果没有指定添加到哪个区域中,则默认添加到中间区域中;
- 如果向同一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件;
构造方法 | 方法功能 |
---|---|
BorderLayout() | 使用默认的水平间距、垂直间距创建BorderLayout布局管理器。 |
BorderLayout(int hgap,int vgap) | 使用指定的水平间距、垂直间距创建BorderLayout布局管理器。 |
示例代码:
public class Demo04 {
public static void main(String[] args){
Frame frame = new Frame();
frame.setLayout(new BorderLayout(20,20));
frame.add(new Button("Top"),BorderLayout.NORTH);
frame.add(new Button("Left"),BorderLayout.WEST);
frame.add(new Button("Right"),BorderLayout.EAST);
frame.add(new Button("Bottom"),BorderLayout.SOUTH);
frame.add(new Button("Center"),BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
GridLayout
GridLayout布局管理器将容器分隔成纵横线分隔的网格,每个网格所占的区域大小相同。当向使用GridLayout布局管理器的容器中添加组件时,默认从左向右、从上向下一次添加到每个网格中。与FlowLayout不同的是,放置在GridLayout布局管理器中的各组件的大小由组件所处的区域决定(每个组件将自动占满整个区域)。
构造方法 | 方法功能 |
---|---|
GridLayout(int rows,int cols) | 采用指定的行数、列数,以及默认的横向间距、纵向间距将容器分割成多个网格 |
GridLayout(int rows,int cols,int hgap,int vgap) | 采用指定的横向间距、纵向间距将容器分隔成多个网格。 |
示例代码:
public class Demo05 {
public static void main(String[] args){
Frame frame = new Frame("计算器");
Panel p = new Panel();
p.add(new TextField(30));
frame.add(p,BorderLayout.NORTH);
Panel p2 = new Panel();
p2.setLayout(new GridLayout(3,5,0,0));
for(int i = 0; i<10;i++){
p2.add(new Button(String.valueOf(i)));
}
p2.add(new Button("+"));
p2.add(new Button("-"));
p2.add(new Button("*"));
p2.add(new Button("/"));
p2.add(new Button("."));
frame.add(p2);
frame.pack();
frame.setVisible(true);
}
}
GridBagLayout
GridBagLayout 布局管理器的功能最强大,但也最复杂,与GridLayout布局管理器不同的是,在GridBagLayout布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各网格的大小互不相同,从而增加了布局的灵活性。当窗口的大小发生变化时,GridBagLayout布局管理器也可以准确地控制窗口各部分的拉伸。
由于在GridBagLayout布局中,每个组件可以占用多个网格,此时,我们往容器中添加组件的时候,就需要具体地控制每个组件占用多少个网格,java提供的GridBagConstaints类,与特定的组件绑定,可以完成具体大小和跨越性的设置。
CardLayout
CardLayout布局管理器以事件而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的那个Component才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌才可见。
方法名称 | 方法功能 |
---|---|
CardLayout | 创建默认的CardLayout布局管理器。 |
CardLayout(int hgp,int vgap) | 通过指定卡片与容器左右边界的间距(hgap)、上下边界(vgap)的间距来创建CardLayout布局管理器 |
first(Container target) | 显示target容器中的第一张卡片 |
last(Container target) | 显示target容器中的最后一张卡片 |
previous(Container target) | 显示target容器中的前一张卡片 |
show(Container target,String name) | 显示target容器中指定名字的卡片 |
BoxLayout
为了简化开发,Swing引入了一个新的布局管理器:BoxLayout。BoxLayout可以在垂直和水平两个方向上摆放GUI组件,BoxLayout提供了如下一个简单的构造器:
方法名称 | 方法功能 |
---|---|
BoxLayout(Container target ,int axis) | 指定创建基于target容器的BoxLayout布局管理器,该布局管理器里的组件按axis方法排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向。 |
示例代码:
public class Demo06 {
public static void main(String[] args) {
Frame frame = new Frame();
BoxLayout boxLayout = new BoxLayout(frame,BoxLayout.Y_AXIS);
frame.add(new Button("one"));
frame.add(new Button("tow"));
frame.add(new Button("three"));
frame.setLayout(boxLayout);
frame.pack();
frame.setVisible(true);
}
}
在java.swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数情况下,使用Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成整体窗口布局。
方法名称 | 方法功能 |
---|---|
static Box createHorizontalBox() | 创建一个水平排列组件的Box容器。 |
static BoxcreateVerticalBox() | 创建一个垂直排列组件的Box容器。 |
示例代码:
public class Demo01 {
public static void main(String[] args){
Frame frame = new Frame();
Box hBox = Box.createHorizontalBox();
Box vBox = Box.createVerticalBox();
hBox.add(new Button("h btn"));
hBox.add(new Button("h btn"));
vBox.add(new Button("v btn"));
vBox.add(new Button("v btn"));
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
frame.pack();
frame.setVisible(true);
}
}
通过之前的两个BoxLayout演示,我们会发现,被它管理的容器中的组件之间是没有间隔的,不是特别美观,但之前学习的几种布局,组件之间都会有一些间距,那使用BoxLayout如何给组件设置间距呢?
其实很简单,我们只需要在原有的组件需要间隔的地方,添加间隔即可,而每个间隔可以是一个组件,只不过该组件没有内容,仅仅起到一种分隔的作用。
Box类中,提供了五个方便的静态方法来生成这些间隔组件:
方法名称 | 功能方法 |
---|---|
static Component createHorizontalGlue() | 创建一条水平Glue(可以在两个方向上同时拉伸个间距) |
static Component createVerticalGlue() | 创建一条垂直Glue(可在两个方向上同时拉伸间距) |
static Component createHorizontalStrut(int width) | 创建一条指定宽度(宽度固定了,不能拉伸)的水平Strut(可在垂直方向上拉伸的间距) |
static Component createVerticalStrut(int height) | 创建一条指定高度(高度固定了,不能拉伸)的垂直Struct(可在水平方向上拉伸的间距) |
本文来自博客园,作者:maplerain,转载请注明原文链接:https://www.cnblogs.com/maplerain/p/16667144.html 博主B站