JAVA入门教程(2)
JAVA GUI组成Swing的类如图
Swing优点
Swing具有更丰富,更方便的用户界面元素集合。
Swing对低层平台的依赖更少;因此和平台有关的bug也少的多。
Swing给不同平台上的用户一致的感觉。
布局管理器
由Swing开发的GUI界面通常由两种组件构成:
容器组件:用于管理其他界面组件的组件,例如:JFrame,JPanel等。
元素组件:用于构成各种用户界面的组件,例如:JLabel,JTextField等。
容器中组件出现的位置和组件的大小通常由布局管理器控制。每个Container(比如一个JPanel或一个JFrame)都有一个缺省布局管理器,它可以通过调用setLayout()来改变。
布局管理器负责决定布局策略以及其容器的每一个子组件的大小。
Java编程语言包含下面的布局管理器:
FlowLayout- Panel和Applets的缺省布局管理器
BorderLayout- Window、Dialog及Frame的缺省管理程序
GridLayout
CardLayout
GridBagLayout
GridBagLayout
下图描述了容器的默认布局管理器
FlowLayout
前面所用的FlowLayout布局管理器对组件逐行地定位。每完成一行,一个
新行便又开始。与其它布局管理器不一样,FlowLayout布局管理器不限制
它所管理的组件的大小,而是允许它们有自己的最佳大小。Flow布局构造函
数参数允许将组件左对齐或右对齐(缺省为居中)。如果想在组件之间创建一
个更大的最小间隔,可以规定一个界限。
当用户对由Flow布局管理的区域进行缩放时,布局就发生变化。
下面的例子说明如何用容器类的setLayout()方法来创建Flow布局对象并设置它们。
setLayout(new FlowLayout(int align, int hgap, int vgap));
align的值必须是FlowLayout.LEFT, FlowLayout.RIGHT,或
FlowLayout.CENTER。例如:
setLayout(new FlowLayout(FlowLayout.RIGHT, 20, 40));
下述程序构造并设置一个新Flow布局,它带有规定好的对齐方式以及一个缺
省的5单位的水平和垂直间隙。
setLayout(new FlowLayout(FlowLayout.LEFT));
下述程序构造并安装一个新Flow布局,它带有规定好的居中对齐方式和一个
缺省的5单位的水平和垂直间隙。
setLayout(new FlowLayout());
下面的代码将几个按钮添加到框架中的一个Flow布局中:
import java.awt.*;
public class MyFlow {
private Frame f;
private Button button1, button2, button3;
public static void main(String args[]) {
MyFlow mflow = new MyFlow();
mflow.go();
}
public void go() {
f = new Frame("Flow Layout");
f.setLayout(new FlowLayout());
button1 = new Button("Ok");
button2 = new Button("Open");
button3 = new Button("Close");
f.add(button1);
f.add(button2);
f.add(button3);
f.setSize(100, 100);
f.setVisible(true);
}
}
BorderLayout
BorderLayout布局管理器为在一个Panel或Window中放置组件提供一
个更复杂的方案。BorderLayout布局管理器包括五个明显的区域:东、南、
西、北、中。
北占据面板的上方,东占据面板的右侧,等等。中间区域是在东、南、西、
北都填满后剩下的区域。当窗口垂直延伸时,东、西、中区域也延伸;而当
窗口水平延伸时,东、西、中区域也延伸。
BorderLayout布局管理器是用于Dialog和Frame的缺省布局管理器。
其划分界面如图
下面这一行构造并安装一个新Border布局管理器,在组件之间没有间隙:
setLayout(new BorderLayout());
这一行构造并安装一个Border布局,在组件之间有由hgap和 vgap 规定的间隙:
setLayout(new BorderLayout(int hgap, int vgap);
在向使用BorderLayout布局管理器管理的界面添加组件时,默认的将加入
到中间,如果添加的其它组件未指定添加方位将互相覆盖,只有最后添加上
去的组件方可看见。
下面的代码对前例进行了修改,表示出了Border布局管理器的特性。可以
用从Container类继承的setLayout()方法来将布局设定为Border布
局。
import java.awt.*;
public class ExGui2 {
private Frame f;
private Button bn, bs, bw, be, bc;
public static void main(String args[]) {
ExGui2 guiWindow2 = new ExGui2();
guiWindow2.go();
}
public void go() {
f = new Frame("Border Layout");
bn = new Button("B1");
bs = new Button("B2");
be = new Button("B3");
bw = new Button("B4");
bc = new Button("B5");
f.add(bn, BorderLayout.NORTH);
f.add(bs, BorderLayout.SOUTH);
f.add(be, BorderLayout.EAST);
f.add(bw, BorderLayout.WEST);
f.add(bc, BorderLayout.CENTER);
f.setSize(200, 200);
f.setVisible(true);
}
}
这段代码产生如图效果
GridLayout
GridLayout布局管理器为放置组件提供了灵活性。用行和列来创建管
理器。然后组件就填充到由管理器规定的单元中。比如,由语句new
GridLayout(3,2)创建的有三行两列的GridLayout布局能产生如图
的六个单元:
像BorderLayout布局管理器一样,GridLayout布局管理器中的组件相应的位置不随区域的缩放而改变。只是组件的大小改变。GridLayout布局管理器总是忽略组件的最佳大小。所有单元的宽度是相同的,是根据单元数对可用宽度进行平分而定的。同样地,所有单元的高度是相同的,是根据行数对可用高度进行平分而定的。将组件添加到网格中的命令决定它们占有的单元。单元的行数是从左到右填充,就象文本一样,而列是从上到下由行填充。
程序行:setLayout(new GridLayout());创建并安装一个Grid布局,
仅有一行一列。
程序行:setLayout(new GridLayout(int rows, int cols));创
建并安装一个带有规定好行数和栏数的Grid布局。
程序行:setLayout(new GridLayout(int rows, int cols, int
hgap, int vgap); 创建并安装一个带有规定好行数和栏数的网格布局。
hgap和vgap规定组件间各自的间隙。水平间隙放在左右两边及栏与栏之间。
垂直间隙放在顶部、底部及每行之间。
import java.awt.*;
public class GridEx {
private Frame f;
private Button b1, b2, b3, b4, b5, b6;
public static void main(String args[]) {
GridEx grid = new GridEx();
grid.go();
}
public void go() {
f = new Frame("Grid example");
f.setLayout(new GridLayout(3, 2));
b1 = new Button("1");
b2 = new Button("2");
b3 = new Button("3");
b4 = new Button("4");
b5 = new Button("5");
b6 = new Button("6");
f.add(b1);
f.add(b2);
f.add(b3);
f.add(b4);
f.add(b5);
f.add(b6);
f.pack();
f.setVisible(true);
}
}
CardLayout
Card布局管理器能将界面看作一系列的卡片,在任何时候都仅能看到其中的
一个。用add()方法来将卡添加到Card布局中。Card布局管理器的show()
方法将请求转换到一个新卡中。下图就是一个带有5张卡片的框架。
鼠标点击左面板将视图转换到右面板,等等。
用来创建上图框架的代码段如下所示:
import java.awt.*;
import java.awt.event.*;
public class CardExample implements MouseListener {
Panel p1, p2, p3, p4, p5;
Label l1, l2, l3, l4, l5;
private CardLayout myCard;
private Frame f;
public CardExample() {
f = new Frame("Card Test");
myCard = new CardLayout();
p1 = new Panel();
p2 = new Panel();
p3 = new Panel();
p4 = new Panel();
p5 = new Panel();
l1 = new Label("This is the first Panel");
l2 = new Label("This is the second Panel");
l3 = new Label("This is the third Panel");
l4 = new Label("This is the fourth Panel");
l5 = new Label("This is the fifth Panel");
}
public void launchFrame() {
f.setLayout(myCard);
p1.setBackground(Color.yellow);
p1.add(l1);
p2.setBackground(Color.green);
p2.add(l2);
p3.setBackground(Color.magenta);
p3.add(l3);
p4.setBackground(Color.white);
p4.add(l4);
p5.setBackground(Color.cyan);
p5.add(l5);
p1.addMouseListener(this);
p2.addMouseListener(this);
p3.addMouseListener(this);
p4.addMouseListener(this);
p5.addMouseListener(this);
f.add(p1, "First");
f.add(p2, "Second");
f.add(p3, "Third");
f.add(p4, "Fourth");
f.add(p5, "Fifth");
myCard.show(f, "First");
f.setSize(200, 200);
f.setVisible(true);
}
//用于处理鼠标点击事件
public void mousePressed(MouseEvent e) {
myCard.next(f);
}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public static void main(String args[]) {
CardExample ct = new CardExample();
ct.launchFrame();
}
}
GridBagLayout
除了Flow、Border、Grid和Card布局管理器外,核心Java.awt也提
供GridBag布局管理器。
GridBag布局管理器在网格的基础上提供复杂的布局,但它允许单个组件在
一个单元中而不是填满整个单元那样地占用它们的最佳大小。网格包布局
管
理器也允许单个组件扩展成不止一个单元。
实例分析
例1:组成用户登录的界面包括用户名和密码输入并可以确认提交,请使用Swing组件编写
解决方案
n 问题分析
n 使用组件分析
n 编写代码
n 编译并运行
问题分析
可以使用Swing中的GUI类构建登录界面,注意区别元素组件和容器组件
使用组件分析
基本元素组件
n JLabel: 用于短文本字符串或图像或二者的显示区。
n JTextField: 用于单行输入文本。
n JButton: 按钮的实现。
n JTextArea: 显示纯文本的多行区域。
n JComboBox: 下拉列表组合的组件。
n JRadioButton: 实现一个单选按钮,此按钮项可被选择或取消选择.
n JCheckBox: 复选框的实现
创建框架
Java中的顶层窗口(即:那些没有包含在其他窗口中的窗口)被称为框架,
也称为容器组件。
n JPanel: 一般轻量级容器,不能直接显示.
n JFrame: 是带有标题和边界的顶层窗口.
n JApplet:一种不适合单独运行但可嵌入在其他应用程序中的小程序。
注解:大部分Swing组件类的名字都是以"J"开头,如JButton,JFrame,JTextField等等。Java中也有着Button,Frame类,不过它们都是AWT组件。如果你不小心忘了写Swing组件前的"J",程序还是很可能能够编译和运行,不过由于混杂了Swing和AWT组件,在视觉和响应上可能会有不一致的地方。
给框架定位
JFrame类本身只有几个用来改变框架外观的类。当然,通过继承,JFrame
从不同的超类中继承来很多用于处理框架大小和位置的方法。下面列出几个
可能最为重要的方法:
n dispose方法----关闭窗口并回收用于创建窗口的任何资源;
n setIconImage方法----当窗口最小化时,把一个Image对象用作图标。
n setTitle方法-----改变标题栏中的文字。
n setResizable方法-使用boolean参数来决定框架大小是否能被用户改变。
n setLocation方法----用来显示组件在容器中的位置(对于框架来说,方法中的参数坐标是相对于整个屏幕而言的,对于容器内的组件,坐标是相对于容器的)。
n setBounds方法----同上,只不过它带有四个参数(其中前两个参数同上,都是设置组件的位置,后两个参数用来设置组件的大小)。
在面板中显示信息
JFram与Frame不同的是,在JFrame中加组件是加在内容窗格里的。如:
Container contentPane=frame.getContentPane(); //用上例中的 frame对象
JComponent c=…;
contentPane.add(c);
如果你只需要在框架中显示一个Swing组件,那么你可以用下面的方式把组
件放置到内容窗格中。
Frame.setContentPane(c);
面板是也是个容器。它可以再放其他的组件,我们可以设计自己的面板:
n 定义一个扩展JPanel的新类
n 覆盖paintComponent方法
注意:paintComponent方法实际上定义在JComponent中,这个类是所有非窗口Swing组件的父类。该方法有一个Graphics类型的参数。Graphics 对象存储了一个用于绘制图形和文本的设置集合(比如字体和当前颜色)。Java中的所有绘制都必须用Graphics对象。它拥有绘制,图案,图象和文本的方法。
例如:SimpleJFrameTest.java
import javax.swing.*;
import java.awt.*;
public class SimpleJFrameTest {
public static void main(String[] args) {
SimpleJFrame fram = new SimpleJFrame();
fram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fram.show();
// fram.setVisible(true);
}
}
class SimpleJFrame extends JFrame {
public static final int WIDTH = 400;
public static final int HEIGHT = 300;
public SimpleJFrame() {
setSize(WIDTH, HEIGHT);
Container contentPane = getContentPane();
contentPane.add(new JPanelOne());
}
}
class JPanelOne extends JPanel {
public void paint(Graphics g) {
super.paint(g);
g.fillRect(30, 10, 200, 100);
g.clearRect(60, 30, 80, 40);
g.drawRect(70, 45, 35, 20);
g.drawLine(10, 60, 250, 60);
}
}
结果
定义元素组件:
JLabel lblUsername;
JLable lblPassword;
JTextField txtUsername;
JPasswordField txtPassword;
JButton bLogin;
定义容器组件:
JPanel panel;
编写代码
import java.awt.*;
import javax.swing.*;
public class UserLogin extends JFrame {
JLabel lblUsername;
JLabel lblPassword;
JTextField txtUsername;
JPasswordField txtPassword;
JButton bLogin;
JPanel panel;
public UserLogin() {
panel = (JPanel) getContentPane();
// 设置布局管理器
panel.setLayout(new FlowLayout());
lblUsername = new JLabel("Usernanme:");
lblPassword = new JLabel("Password:");
txtUsername = new JTextField(10);
txtPassword = new JPasswordField(10);
bLogin = new JButton("Login");
panel.add(lblUsername);
panel.add(txtUsername);
panel.add(lblPassword);
panel.add(txtPassword);
panel.add(bLogin);
setTitle("User Login");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(250, 150);
setVisible(true);
}
public static void main(String[] args) {
new UserLogin();
}
}
编译并运行
例2:组成用户登录的界面已经设计完成,使用合理的布局管理器管理界面元
素,请使用Swing组件编写
解决方案
n 问题分析
n 使用布局管理器分析
n 编写代码
n 编译并运行
问题分析
可以使用使用GridBagLayout管理布局
使用布局管理器分析
GridBagLayout
与GridLayout类似,GridBagLayout将组件在一个矩形的"单元"网格中对齐。GridLayout和GridBagLayout的区别在于,GridBagLayout使用了一种称为GridBagConstraints的对象。
通过在GridBagConstraints对象中设置值,组件可水平或垂直地对齐(带
有或不带有小插图和填充),被告知扩展以填充给定的区域,以及被指示如何
对窗口大小的改变采取相应的行动。
GridBagConstraints
GridBagConstraints的成员变量用于控制组件布局它们是:
n gridx和gridy
这些变量指定了位于组件显示区域左上方的单元的特征(也就是组件出现的
x,坐标值),其中,最左上方的单元具有地址gridx=0,gridy=0。
n gridwidth和gridheight
这些变量指定了在组件的显示区域中,行(gridwidth)或列(gridheight)
中的单元数目。缺省值为1。你可用GridBagConstraints.REMAINDER
来指定某组件在其行(gridwidth)或列(gridheight)中为最后一个。
用GridBagConstraints.RELATIVE可指定某组件在其行(gridwidth)
或列(gridheight)中与最后一个相邻。
n fill
fill在某组件的显示区域大于它所要求的大小时被使用;fill决定了是否
(和怎样)改变组件的大小。有效值为GridBagConstraints.NONE(缺
省),GridBagConstraints.HORIZONTAL(使该组件足够大以填充其显
示区域的水平方向,但不改变其高度),GridBagConstraints.VERTICAL
(使该组件足够大,以填充其显示区域的垂直方向,但不改变其宽度),
GridBagConstraints.BOTH(使该组件填充其整个显示区域)。
n ipadx和ipady
这些变量指定了内部填充;即,在该组件的最小尺寸基础上还需增加多少。
组件的宽度必须至少为其最小宽度加ipadx*2个象素(因为填充作用于组件
的两边)。同样地,组件的高度必须至少为其最小高度加ipady*2个象素。
n insets
insets指定了组件的外部填充;即,组件与其显示区域边界之间的最小空间大小。
n anchor
本变量在组件小于其显示区域时使用;anchor决定了把组件放置在该区域中的位置。有效值为GridBagConstraints.CENTER(缺省),.NORTH,.NORTHEAST,.EAST,.SOUTHEAST,.SOUTH,.SOUTHWEST,.WEST,和.NORTHWEST。
n weightx和weighty
这些变量用来决定如何分布空白和改变它的大小。除非你为一行(weightx)
和一列(weighty)中至少一个组件指定了重量,否则,所有组件都会集中
在容器的中央。这是因为,当重量为0(缺省值)时,GridBagLayout在其
单元网格间以及容器边界加入一些额外的空白。
结果
GridBagLayout gb;
GridBagConstraints gbc;
....
gb = new GridBagLayout();
gbc = new GridBagConstraints();
panel.setLayout(gb);
...
gbc.gridx = 1;
gbc.gridy = 1;
gb.setConstraints(lblUsername,gbc);
panel.add(lblUsername);
编写代码
import java.awt.*;
import javax.swing.*;
public class UserLoginFrame extends JFrame {
JLabel lblUsername;
JLabel lblPassword;
JTextField txtUsername;
JPasswordField txtPassword;
JButton bLogin;
JPanel panel;
GridBagLayout gb;
GridBagConstraints gbc;
public UserLoginFrame() {
panel = (JPanel) getContentPane();
gb = new GridBagLayout();
gbc = new GridBagConstraints();
// 设置布局管理器
panel.setLayout(gb);
lblUsername = new JLabel("Usernanme:");
lblPassword = new JLabel("Password:");
txtUsername = new JTextField(10);
txtPassword = new JPasswordField(10);
bLogin = new JButton("Login");
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 1;
gbc.gridy = 1;
gb.setConstraints(lblUsername, gbc);
panel.add(lblUsername);
gbc.gridx = 2;
gbc.gridy = 1;
gb.setConstraints(txtUsername, gbc);
panel.add(txtUsername);
gbc.gridx = 1;
gbc.gridy = 2;
gb.setConstraints(lblPassword, gbc);
panel.add(lblPassword);
gbc.gridx = 2;
gbc.gridy = 2;
gb.setConstraints(txtPassword, gbc);
panel.add(txtPassword);
gbc.gridx = 2;
gbc.gridy = 3;
gb.setConstraints(bLogin, gbc);
panel.add(bLogin);
setTitle("User Login");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(250, 250);
setVisible(true);
}
public static void main(String[] args) {
new UserLoginFrame();
}
}
编译并运行
[ 本帖最后由 lampeter123 于 2010-7-21 11:27 编辑 ]