程序被设计出来,为了方便用户使用,一定是需要界面设计的
GUI技术以及支持包:
AWT:提供大量类和接口
Swing 是一个为Java设计的GUI工具包,JAVA基础类的一部分。Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表。
AWT:java.awt
包
Swing:javax.swing
包
本篇作为上篇,先介绍组件容器与布局管理器等知识点
创建图形用户界面的一般步骤:
创建容器–设置布局管理器–添加组件–事件处理
常用的组件与容器
Swing中的容器分类:
1.顶级容器:一般是一个顶层窗口(框架)
JFrame:用于框架窗口的类,应用程序至少使用一个框架窗口
JDialog:用于对话框的类
2.中间容器
JPanel:面板,是最灵活最常用的中间容器
JScrollPane:与JPanel类似,但还可以在大的组件或可扩展组件周围提供滚动条
JToolBar:按行或列排列一组组件(通常是按钮)
JFrame
在Swing程序中创建顶层窗口,允许将标签、按钮、文本框等组件添加其中
所有的JFrame框架顶层都有一个JRootPane面板,对于具有单一面板的窗体(JFrame),可以使用getContentPane()方法取得,并使用add()方法将组件加到面板上。

setResizable(false)可以使最大化按钮失效
默认情况下,当用户关闭一个框架时,该框架会隐藏起来,而程序不会终止
dispose关闭窗口,并回收该窗口的所有资源(Windows)
参考示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import javax.swing.*;
public class Main {
public static void main(String[] args) { JFrame f = new JFrame("第一个java窗口"); f.setSize(300,200); f.setLocationRelativeTo(null); f.setVisible(true); f.setResizable(false); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
|
运行之后的效果如图所示:

若想要改变框架的颜色,不能直接设置,必须设置框架内置的面板的颜色,如下所示:
1
| f.getContentPane().setBackground(Color.BLACK);
|
窗口就变成了

JPanel
JPanel面板是中间容器,没有标题,不能独立存在,必须将其添加到其它容器中。
面板与框架类似,也是一种容器,可以容纳其它GUI组件
JPanel类具有两个有用的特性:
本身是一个中间容器,能够容纳按钮、滚动条、文本框等用户界面元素;
有一个能够在上面进行绘制的表面,用来画文本和图形。

注意:坐标原点(0,0)在屏幕(或组件)的左上角,坐标单位是像素

参考示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import javax.swing.*; import java.awt.Color;
public class Main {
public static void main(String[] args) { JFrame f = new JFrame("JPanel示例"); f.setSize(300,200); f.setLayout(null); JPanel panel = new JPanel(); panel.setSize(150,100); panel.setBackground(Color.CYAN); f.add(panel); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
|
运行之后效果如图所示:

JButton(按钮)是常用组件之一,可以显示文本或图标

创建文本按钮:
1
| JButton button = new JButton("确定");
|
创建图标按钮:
1 2 3
| ImageIcon imageIcon = new ImageIcon("pict.jpg"); imageIcon.setImage(imageIcon.getImage().getScaledInstance(40,20,Image.SCALE_DEFAULT)); JButton button = new JButton(imageIcon);
|
创建带文本和图标的按钮:
1
| JButton button = new JButton("确定",imageIcon);
|

示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import javax.swing.*; import java.awt.FlowLayout;
public class Main {
public static void main(String[] args) { JFrame f = new JFrame("JButton示例"); f.setSize(300,200); JButton buttonOK,buttonCancel; f.setLayout(new FlowLayout()); buttonOK = new JButton("确定"); buttonCancel = new JButton("取消"); f.add(buttonOK); f.add(buttonCancel); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
|
运行效果如下:

布局管理器
布局管理器负责确定每个组件的大小以及位置,当容器发生变化后还能够进行动态调整。
因为Java的组件不使用坐标这种绝对定位的形式,使用布局管理器进行定位能够使得程序界面自动适应不同分辨率的屏幕。
在使用布局管理器时,用户无法自己设置组件的大小和位置,即setLocation(),setSize(),setBounds()均无效
布局管理器的分类:
FlowLayout(流式布局):Panel和Applet的缺省布局管理器
BorderLayout(边界布局):JDialog和JFrame的缺省布局管理器,适合顶层容器使用
GridLayout(网络布局):适合按钮类组件的布局
GridBagLayout(网格组布局)
CardLayout(卡片布局):适合多功能程序使用
BoxLayout(箱式布局)
SpringLayout(弹簧布局)
每个容器都有缺省的布局管理器,在没有设置新的布局前,在容器中添加组件都按照该容器的缺省布局排列。
FlowLayout

align表示对齐方式,取值为常量
每行组件默认居中对齐,组件之间的水平间距和垂直间距默认是5个像素
流式布局的优点:使用组件的最佳尺寸
流式布局的缺点:改变容器大小,组件相对位置会发生变化
设置默认的FlowLayout布局
1
| f.setLayout(new FlowLayout());
|
设置框架f为组件左对齐的FlowLayout布局,并且组件的水平间距为20像素,垂直间距为40像素
1
| f.setLayout(new FlowLayout(FlowLayout.LEFT,20,40));
|
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import javax.swing.*; import java.awt.*;
class FlowLayoutDemo { public FlowLayoutDemo(String title) { JFrame f = new JFrame("FlowLayoutDemo"); f.setSize(260,150); JButton button1 = new JButton("第一个按钮"); JButton button2 = new JButton("第二个按钮"); JButton button3 = new JButton("第三个按钮"); JButton button4 = new JButton("第四个按钮"); JButton button5 = new JButton("第五个按钮"); f.setLayout(new FlowLayout()); f.add(button1); f.add(button2); f.add(button3); f.add(button4); f.add(button5); f.setVisible(true); } public static void main(String[] args) { new FlowLayoutDemo("FlowLayout"); } }
|

BorderLayout
边界布局管理器的布局分为五个位置:CENTER、EAST、WEST、NORTH、SOUTH
可以把组件放到任意一个位置,缺省位置是CENTER

每个区域只能添加一个组件,若添加多个,只能显示一个,如果想在一个区域添加多个组件,则必须先在该区域放一个容器,再将多个组件放在该容器。
优点:容器形状变化,组件相对位置不会变化,各区域和各组件大小会改变
North和South区域的高度保持不变
East和West区域的宽度保持不变
Center区域的组件随着容器的大小的变化而变化
缺点:直接使用该布局管理器只能放置五个组件
注意:不是组件之间的间距,是区域之间的间距。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import javax.swing.*; import java.awt.*;
class BorderLayoutDomo { public BorderLayoutDomo(String title) { JFrame f = new JFrame(title); f.setLayout(new BorderLayout(2,2)); f.add(BorderLayout.NORTH,new JButton("North")); f.add(BorderLayout.SOUTH,new JButton("South")); f.add(BorderLayout.EAST,new JButton("East")); f.add(BorderLayout.WEST,new JButton("West")); f.add(BorderLayout.CENTER,new JButton("Center")); f.setSize(260,180); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { BorderLayoutDomo domo= new BorderLayoutDomo("Exanple"); } }
|

GridLayout
网络布局管理器将容器的空间划分为若干行和列的网格,每个网格大小相同
各组件的排列方式:从上到下,从左到右
组件放入容器的次序决定了它在容器中的位置
默认间距是0

网格每列宽度相同,等于容器的宽度除以网格的列数
网格每行高度相同,等于容器的高度除以网格的行数
容器大小改变时,组件的相对位置不变,大小会改变
若组件数超过网格设定的个数,则布局管理器会自动增加网格个数,原则是保持行数不变。
优点:不受组件数量的限制
缺点:每个组件会占据网格全部的大小,自身的尺寸无法体现
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import javax.swing.*; import java.awt.*;
class GridLayoutDemo { JButton button1,button2,button3,button4,button5; GridLayoutDemo() { JFrame f = new JFrame("GridLayout"); f.setLayout(new GridLayout(3,2)); button1 = new JButton("按钮1"); button2 = new JButton("按钮2"); button3 = new JButton("按钮3"); button4 = new JButton("按钮4"); button5 = new JButton("按钮5"); f.add(button1); f.add(button2); f.add(button3); f.add(button4); f.add(button5); f.setSize(260,180); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new GridLayoutDemo(); } }
|
运行效果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import javax.swing.*; import java.awt.*;
class GridFrame { JButton btn[]; public GridFrame() { JFrame f = new JFrame("网格布局演示"); String str[]={"1","2","3","4","5","6","7","8","9"}; Container contentpane = f.getContentPane(); contentpane.setLayout(new GridLayout(3,3,2,2)); btn=new JButton[str.length]; for (int i=0;i<str.length;i++){ btn[i]=new JButton(str[i]); contentpane.add(btn[i]); } f.setSize(200,200); f.setVisible(true); f.setLayout(new GridLayout(3,3,2,2)); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new GridFrame(); } }
|

网格布局在组织窗口的局部区域比较有用
如果需要一行或者多行相同尺寸的按钮,可以把按钮放在一个面板里,该面板使用网格布局进行管理。
CardLayout
将容器中的组件处理为一系列卡片,每一时刻只显示其中的一张卡片,可以在卡片之间进行切换。
此种布局方式可以帮助用户处理两个或者更多的组件共享同一显示空间,共享空间的组件之间的关系就像是一摞牌,只有最上面的组件是可见的。

CardLayyout类有二种构造方法:
public CardLayout():
组件距容器左右边界和上下边界的距离为缺省值0个像素
public CardLayout(int horizontalGap,int verticalGap):
组件距容器左右边界和上下边界的距离为指定值
每张牌中只能放置一个组件,如果想在一张牌中放置多个组件,则必须先在该牌放一个容器,再将多个组件放在该容器中
向容器中添加组件时可以为组件取一个名字,以提供更换显示组件时使用:
add(Component,String);
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import javax.swing.*; import java.awt.*; import java.awt.event.*;
class CardTest extends MouseAdapter{ JFrame f; Container contentPane; CardLayout myCard; Container c; JPanel p1,p2,p3; JLabel l1,l2,l3; CardTest(){ f=new JFrame("Card Test"); contentPane = f.getContentPane(); myCard = new CardLayout(); f.setLayout(new CardLayout()); f.setSize(300,200); f.setVisible(true); p1=new JPanel(); p2=new JPanel(); p3=new JPanel(); p1.setBackground(Color.ORANGE); l1=new JLabel("first"); p1.add(l1); p2.setBackground(Color.pink); l2=new JLabel("2nd"); p2.add(l2); p3.setBackground(Color.CYAN); l3=new JLabel("3rd"); p3.add(l3); c = f.getContentPane(); c.add(p1,"First"); c.add(p2,"Second"); c.add(p3,"Third"); contentPane.setLayout(myCard); myCard.show(c,"First"); p1.addMouseListener(this); p2.addMouseListener(this); p3.addMouseListener(this); } public void mouseClicked(MouseEvent e){ myCard.next(c); } public static void main(String[] args) { CardTest ct = new CardTest(); } }
|
运行结果,鼠标点击可以切换:


