10 第十章 JAVA GUI概述.docx
《10 第十章 JAVA GUI概述.docx》由会员分享,可在线阅读,更多相关《10 第十章 JAVA GUI概述.docx(25页珍藏版)》请在冰点文库上搜索。
10第十章JAVAGUI概述
第十章:
JAVAGUI概述
学习目标
⏹GUI概述及组成
⏹SWING优点
⏹使用布局管理器
⏹GUI实例分析
GUI概述及组成
Java1.0刚出现时,包含一个用于基本GUI编程的类库,Sun把它叫做抽象窗口工具箱(AbstractWindowToolkit,AWT)。
AWT库处理用户界面元素的方法是把这些元素的创建及其行为委托给每个目标平台(Windows,Solaris,Macintosh等)的本地GUI工具进行处理。
不同平台的AWT用户界面存在着不同的bug。
程序员们必须在每一个平台上测试他们的应用程序,他们因此嘲笑AWT是"一次编写,到处调试"。
1996年,Netscape开发了一个工作方式完全不同的GUI库,并把它叫做IFC(InternetFoundationClasses,因特网基础类集)。
包括用户界面元素,如按钮,菜单等。
并且使用IFC部件的程序运行在所有平台上看起来都一样。
Sun和Netscape合作完善了这种方法,创建了一个新的用户界面库,它的代码名是"Swing"。
从此才真正实现了"一次编写,到处运行"的口号。
Swing只是提供了更好的用户界面组件。
AWT的基本体系结构,尤其是事件处理模型,从Java1.1版后并没有改变。
组成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布局管理器对组件逐行地定位。
每完成一行,一个
新行便又开始。
与其它布局管理器不一样,FlowLayout布局管理器不限制
它所管理的组件的大小,而是允许它们有自己的最佳大小。
Flow布局构造函
数参数允许将组件左对齐或右对齐(缺省为居中)。
如果想在组件之间创建一
个更大的最小间隔,可以规定一个界限。
当用户对由Flow布局管理的区域进行缩放时,布局就发生变化。
如图10.3:
下面的例子说明如何用容器类的setLayout()方法来创建Flow布局对象并设置它们。
setLayout(newFlowLayout(intalign,inthgap,intvgap));
align的值必须是FlowLayout.LEFT,FlowLayout.RIGHT,或
FlowLayout.CENTER。
例如:
setLayout(newFlowLayout(FlowLayout.RIGHT,20,40));
下述程序构造并设置一个新Flow布局,它带有规定好的对齐方式以及一个缺
省的5单位的水平和垂直间隙。
setLayout(newFlowLayout(FlowLayout.LEFT));
下述程序构造并安装一个新Flow布局,它带有规定好的居中对齐方式和一个
缺省的5单位的水平和垂直间隙。
setLayout(newFlowLayout());
下面的代码将几个按钮添加到框架中的一个Flow布局中:
importjava.awt.*;
publicclassMyFlow{
privateFramef;
privateButtonbutton1,button2,button3;
publicstaticvoidmain(Stringargs[]){
MyFlowmflow=newMyFlow();
mflow.go();
}
publicvoidgo(){
f=newFrame("FlowLayout");
f.setLayout(newFlowLayout());
button1=newButton("Ok");
button2=newButton("Open");
button3=newButton("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(newBorderLayout());
这一行构造并安装一个Border布局,在组件之间有由hgap和vgap规定的间隙:
setLayout(newBorderLayout(inthgap,intvgap);
在向使用BorderLayout布局管理器管理的界面添加组件时,默认的将加入
到中间,如果添加的其它组件未指定添加方位将互相覆盖,只有最后添加上
去的组件方可看见。
下面的代码对前例进行了修改,表示出了Border布局管理器的特性。
可以
用从Container类继承的setLayout()方法来将布局设定为Border布
局。
importjava.awt.*;
publicclassExGui2{
privateFramef;
privateButtonbn,bs,bw,be,bc;
publicstaticvoidmain(Stringargs[]){
ExGui2guiWindow2=newExGui2();
guiWindow2.go();
}
publicvoidgo(){
f=newFrame("BorderLayout");
bn=newButton("B1");
bs=newButton("B2");
be=newButton("B3");
bw=newButton("B4");
bc=newButton("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);
}
}
这段代码产生如图10.5效果
GridLayout
GridLayout布局管理器为放置组件提供了灵活性。
用行和列来创建管
理器。
然后组件就填充到由管理器规定的单元中。
比如,由语句new
GridLayout(3,2)创建的有三行两列的GridLayout布局能产生如图
的六个单元:
像BorderLayout布局管理器一样,GridLayout布局管理器中的组件相应的位置不随区域的缩放而改变。
只是组件的大小改变。
GridLayout布局管理器总是忽略组件的最佳大小。
所有单元的宽度是相同的,是根据单元数对可用宽度进行平分而定的。
同样地,所有单元的高度是相同的,是根据行数对可用高度进行平分而定的。
将组件添加到网格中的命令决定它们占有的单元。
单元的行数是从左到右填充,就象文本一样,而列是从上到下由行填充。
程序行:
setLayout(newGridLayout());创建并安装一个Grid布局,
仅有一行一列。
程序行:
setLayout(newGridLayout(introws,intcols));创
建并安装一个带有规定好行数和栏数的Grid布局。
程序行:
setLayout(newGridLayout(introws,intcols,int
hgap,intvgap);创建并安装一个带有规定好行数和栏数的网格布局。
hgap和vgap规定组件间各自的间隙。
水平间隙放在左右两边及栏与栏之间。
垂直间隙放在顶部、底部及每行之间。
importjava.awt.*;
publicclassGridEx{
privateFramef;
privateButtonb1,b2,b3,b4,b5,b6;
publicstaticvoidmain(Stringargs[]){
GridExgrid=newGridEx();
grid.go();
}
publicvoidgo(){
f=newFrame("Gridexample");
f.setLayout(newGridLayout(3,2));
b1=newButton("1");
b2=newButton("2");
b3=newButton("3");
b4=newButton("4");
b5=newButton("5");
b6=newButton("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张卡片的框架。
鼠标点击左面板将视图转换到右面板,等等。
用来创建上图框架的代码段如下所示:
importjava.awt.*;
importjava.awt.event.*;
publicclassCardExampleimplementsMouseListener{
Panelp1,p2,p3,p4,p5;
Labell1,l2,l3,l4,l5;
privateCardLayoutmyCard;
privateFramef;
publicCardExample(){
f=newFrame("CardTest");
myCard=newCardLayout();
p1=newPanel();
p2=newPanel();
p3=newPanel();
p4=newPanel();
p5=newPanel();
l1=newLabel("ThisisthefirstPanel");
l2=newLabel("ThisisthesecondPanel");
l3=newLabel("ThisisthethirdPanel");
l4=newLabel("ThisisthefourthPanel");
l5=newLabel("ThisisthefifthPanel");
}
publicvoidlaunchFrame(){
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);
}
//用于处理鼠标点击事件
publicvoidmousePressed(MouseEvente){
myCard.next(f);
}
publicvoidmouseReleased(MouseEvente){}
publicvoidmouseClicked(MouseEvente){}
publicvoidmouseEntered(MouseEvente){}
publicvoidmouseExited(MouseEvente){}
publicstaticvoidmain(Stringargs[]){
CardExamplect=newCardExample();
ct.launchFrame();
}
}
GridBagLayout
除了Flow、Border、Grid和Card布局管理器外,核心Java.awt也提
供GridBag布局管理器。
GridBag布局管理器在网格的基础上提供复杂的布局,但它允许单个组件在
一个单元中而不是填满整个单元那样地占用它们的最佳大小。
网格包布局管
理器也允许单个组件扩展成不止一个单元。
实例分析
例1:
组成用户登录的界面包括用户名和密码输入并可以确认提交,请使用Swing组件编写
解决方案
⏹问题分析
⏹使用组件分析
⏹编写代码
⏹编译并运行
问题分析
可以使用Swing中的GUI类构建登录界面,注意区别元素组件和容器组件
使用组件分析
基本元素组件
⏹JLabel:
用于短文本字符串或图像或二者的显示区。
⏹JTextField:
用于单行输入文本。
⏹JButton:
按钮的实现。
⏹JTextArea:
显示纯文本的多行区域。
⏹JComboBox:
下拉列表组合的组件。
⏹JRadioButton:
实现一个单选按钮,此按钮项可被选择或取消选择.
⏹JCheckBox:
复选框的实现
创建框架
Java中的顶层窗口(即:
那些没有包含在其他窗口中的窗口)被称为框架,
也称为容器组件。
⏹JPanel:
一般轻量级容器,不能直接显示.
⏹JFrame:
是带有标题和边界的顶层窗口.
⏹JApplet:
一种不适合单独运行但可嵌入在其他应用程序中的小程序。
注解:
大部分Swing组件类的名字都是以"J"开头,如JButton,JFrame,JTextField等等。
Java中也有着Button,Frame类,不过它们都是AWT组件。
如果你不小心忘了写Swing组件前的"J",程序还是很可能能够编译和运行,不过由于混杂了Swing和AWT组件,在视觉和响应上可能会有不一致的地方。
给框架定位
JFrame类本身只有几个用来改变框架外观的类。
当然,通过继承,JFrame
从不同的超类中继承来很多用于处理框架大小和位置的方法。
下面列出几个
可能最为重要的方法:
⏹dispose方法----关闭窗口并回收用于创建窗口的任何资源;
⏹setIconImage方法----当窗口最小化时,把一个Image对象用作图标。
⏹setTitle方法-----改变标题栏中的文字。
⏹setResizable方法-使用boolean参数来决定框架大小是否能被用户改变。
⏹setLocation方法----用来显示组件在容器中的位置(对于框架来说,方法中的参数坐标是相对于整个屏幕而言的,对于容器内的组件,坐标是相对于容器的)。
⏹setBounds方法----同上,只不过它带有四个参数(其中前两个参数同上,都是设置组件的位置,后两个参数用来设置组件的大小)。
在面板中显示信息
JFram与Frame不同的是,在JFrame中加组件是加在内容窗格里的。
如:
ContainercontentPane=frame.getContentPane();//用上例中的frame对象
JComponentc=…;
contentPane.add(c);
如果你只需要在框架中显示一个Swing组件,那么你可以用下面的方式把组
件放置到内容窗格中。
Frame.setContentPane(c);
面板是也是个容器。
它可以再放其他的组件,我们可以设计自己的面板:
⏹定义一个扩展JPanel的新类
⏹覆盖paintComponent方法
注意:
paintComponent方法实际上定义在JComponent中,这个类是所有非窗口Swing组件的父类。
该方法有一个Graphics类型的参数。
Graphics对象存储了一个用于绘制图形和文本的设置集合(比如字体和当前颜色)。
Java中的所有绘制都必须用Graphics对象。
它拥有绘制,图案,图象和文本的方法。
例如:
SimpleJFrameTest.java
importjavax.swing.*;
importjava.awt.*;
publicclassSimpleJFrameTest{
publicstaticvoidmain(String[]args){
SimpleJFramefram=newSimpleJFrame();
fram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fram.show();
//fram.setVisible(true);
}
}
classSimpleJFrameextendsJFrame{
publicstaticfinalintWIDTH=400;
publicstaticfinalintHEIGHT=300;
publicSimpleJFrame(){
setSize(WIDTH,HEIGHT);
ContainercontentPane=getContentPane();
contentPane.add(newJPanelOne());
}
}
classJPanelOneextendsJPanel{
publicvoidpaint(Graphicsg){
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);
}
}
结果
定义元素组件:
JLabellblUsername;
JLablelblPassword;
JTextFieldtxtUsername;
JPasswordFieldtxtPassword;
JButtonbLogin;
定义容器组件:
JPanelpanel;
编写代码
importjava.awt.*;
importjavax.swing.*;
publicclassUserLoginextendsJFrame{
JLabellblUsername;
JLabellblPassword;
JTextFieldtxtUsername;
JPasswordFieldtxtPassword;
JButtonbLogin;
JPanelpanel;
publicUserLogin(){
panel=(JPanel)getContentPane();
//设置布局管理器
panel.setLayout(newFlowLayout());
lblUsername=newJLabel("Usernanme:
");
lblPassword=newJLabel("Password:
");
txtUsername=newJTextField(10);
txtPassword=newJPasswordField(10);
bLogin=newJButton("Login");
panel.add(lblUsername);
panel.add(txtUsername);
panel.add(lblPassword);
panel.add(txtPassword);
panel.add(bLogin);
setTitle("UserLogin");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(250,150);
setVisible(true);
}
publicstaticvoidmain(String[]args){
newUserLogin();