第十一章awtdocx.docx
- 文档编号:23971812
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:31
- 大小:369.42KB
第十一章awtdocx.docx
《第十一章awtdocx.docx》由会员分享,可在线阅读,更多相关《第十一章awtdocx.docx(31页珍藏版)》请在冰豆网上搜索。
第十一章awtdocx
AWT简介(了解!
!
)
为什么需要GUI?
我们前面编写的程序命令行的,用户的体验度极差。
抽象窗口工具包(AbstractWindowTookit)是为java程序提供建立图形用户界面(GraphicsUserInterfaceGUI)的工具集。
主要包含如下组件:
1.用户界面组件
2.事件处理模型
3.图形图像工具(形状、颜色、字体)
4.布局管理器
AWT的优势:
1.最早的JAVAGUI包,内嵌到JDK中,无需引入其他类,功能稳定
2.AWT组件都是线程安全的
3.界面编程基础.学会AWT,很容易去学swing/SWT等功能较强大的GUI组件.
AWT的缺点:
1.组件的创建完全依赖操作系统实现,导致不同的操作系统下出现不同的外观。
说白了,awt的组件是由操作系统绘制的,我们也说awt组件是重量级的组件。
这个工具包提供了一套与本地图形界面进行交互的接口。
AWT中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系,我们把它称为peers。
也就是说,当我们利用AWT来构件图形用户界面的时候,我们实际上是在利用操作系统所提供的图形库。
由于不同操作系统的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。
为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT不得不通过牺牲功能来实现其平台无关性,也就是说,AWT所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。
由于AWT是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。
AWT并没有为GUI组件提供真正的实现,而是调用运行平台的GUI组件来创建和平台一致的对等体peers,因此程序中Textarea实际上是windows的多行文本域组件的对等体,具有和他相同的行为。
所以,你右键单击textarea会出现菜单…
2.线程安全导致运行速度慢
3.为了保证程序的可移植性,AWT组件集遵循最大公约数原则,即AWT只拥有所有平台上都存在的组件的公有集合。
有些常用的组件不支持,比如:
表、树、进度条等。
字体也只能支持4种。
为什么还需要学习AWT?
实际开发中使用AWT的情况非常少,但是我们仍然有必要学习AWT。
主要原因如下:
1.Swing是在AWT基础上构建的,事件模型和一些支持类(形状、颜色、字体)都一样。
掌握AWT有利于后面学习SWING.Eclipse不是swing开发的,是swt开发的。
2.学习一下GUI编程。
事实上,编程思路和其他语言类似
题外话:
SWT的崛起:
SWT本身仅仅是Eclipse组织为了开发EclipseIDE环境所编写的一组底层图形界面API。
或许是无心插柳,或是有意为之,至今为止,SWT无论是在性能和外观上,都超越了SUN公司提供的AWT和SWING。
目前EclipseIDE已经开发到了3.3版本,SWT已经十分稳定。
这里指的稳定应该包含两层意思(eclipse的中文意思是日食,遮住太阳的意思)一是指性能上的稳定,其中的关键是源于SWT的设计理念。
SWT最大化了操作系统的图形构件API,就是说只要操作系统提供了相应图形的构件,那么SWT只是简单应用JNI技术调用它们,只有那些操作系统中不提供的构件,SWT才自己去做一个模拟的实现。
可以看出SWT的性能上的稳定大多时候取决于相应操作系统图形构件的稳定性。
AWT整体关系
组件和容器
Component是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互,是没有菜单的AWT组件的抽象父类。
封装了如下方法:
getComponentAt(intx,inty)
getFont()
getForeground()
getName()
getSize()
paint(Graphicsg)
repaint()
update()
setVisible(booleanb)
setSize(Dimensiond)
setName(Stringname)
setBounds(intx,inty,intwidhth,intheight)同时设置组件的位置和大小
容器Container是Component的子类,容器对象本身也是组件,是可以装其他组件的组件。
AWT中有如下三种容器类型:
Panel:
就是一个矩形空间,目的就是为其他组件提供空间管理。
特点:
不能独立存在,必须被添加到其他容器中;布局管理器默认是FlowLayout。
Window:
可独立存在的顶级窗口.他有两个子类:
Frame:
常见的窗口。
初始化不可见,需要用setVisible(true)设置为可见。
默认是BorderLayout布局管理器。
Dialog:
创建对话框。
ScollPanel:
增加滚动条用。
简单示例:
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setBounds(200,200,300,300);
Buttonb1=newButton("aaa");
TextFieldfield=newTextField();
frame.add(field);
frame.add(b1);
//frame.setLayout(newFlowLayout());
//frame.pack();
frame.setVisible(true);
}
后面增加的组建把前面的覆盖了,原因是是布局管理器的问题,它默认是BorderLayout。
改为FlowLayout就可以了。
//增加Panel容器
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setBounds(200,200,300,300);
Panelpanel=newPanel();
frame.add(panel);
Buttonb1=newButton("aaa");
TextFieldfield=newTextField();
panel.add(field);
panel.add(b1);
frame.setLayout(newFlowLayout());
frame.pack();
frame.setVisible(true);
}
布局管理器
为什么需要布局管理器?
为了使生成的GUI具有良好的平台无关性,awt中提供了布局管理器来管理容器中组件的布局,而不是直接设置组件位置和大小。
比如:
一个按钮,在windows系统下高10px,宽20px,在linux下可能需要15px,宽25px。
这样直接设置的话,就需要这样做大量的调整工作。
对于一个组件来说,一般都有一个最佳大小(既没有多余空间,也没有内容被遮挡),这个最佳大小一般随平台的不同而不同。
如果让程序员手动控制调整这个最佳大小的话,不现实。
我们可以使用布局管理器来讲组件的大小调整到最佳大小。
程序员要做的只是选择合适的布局管理器即可。
常见的布局管理器:
布局管理器
特点
典型代码
效果
FlowLayout
1.从左到右排列容器中的组件,满了后就折到下一行。
(跟我们书写习惯差不多)
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setBounds(200,200,300,300);
for(inti=0;i<10;i++){
Buttonb1=newButton("按钮"+i);
frame.add(b1);
}
frame.setLayout(newFlowLayout());
frame.setVisible(true);
}
BorderLayout
1.将容器区域分为东南西北中五个区域:
2.添加组件时需要指定到哪个子区域,默认是Center
3.
覆盖问题:
如果同一个区域添加多个组件,后面的会覆盖前面的
4.我们可以通过放置5个子容器,子容器中在放置其他组件。
这样就可以放置远远超过5个的组建喽!
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setLayout(newBorderLayout());
frame.setBounds(200,200,300,300);
Buttonb1=newButton("按钮"+0);
Buttonb2=newButton("按钮"+1);
Buttonb3=newButton("按钮"+2);
Buttonb4=newButton("按钮"+3);
Buttonb5=newButton("按钮"+4);
Buttonb55=newButton("按钮"+44);
frame.add(b1,BorderLayout.SOUTH);
frame.add(b2,BorderLayout.NORTH);
frame.add(b3,BorderLayout.CENTER);
frame.add(b4,BorderLayout.WEST);
frame.add(b5,BorderLayout.EAST);
frame.add(b55,BorderLayout.EAST);
frame.setVisible(true);
}
CardLayout
1.将容器中所有的组件看做一叠卡片,每次只有最上面的卡片才可见。
2.几个常用方法:
first,last,previous,next,show
3.
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setBounds(200,200,300,300);
CardLayoutlayout=newCardLayout();
Panelpanel=newPanel();
panel.setLayout(layout);
Buttonb1=newButton("按钮"+1);
Buttonb2=newButton("按钮"+2);
Buttonb3=newButton("按钮"+3);
panel.add("a",b1);//不加的话,会抛出异常:
java.lang.IllegalArgumentException:
cannotaddtolayout:
constraintmustbeastring
panel.add("b",b2);
panel.add("c",b3);
frame.add(panel);
//layout.first(panel);
layout.last(panel);
frame.setVisible(true);
}
GridLayout
1.将容器按照指定行列进行分割,每个网络格大小相同。
2.默认从左到右,从上到下添加组件
3.当自定义的行数和列数不满足要求,系统会通过计算重新布置网格。
如左边例子,当为3*3放10个组件时,会自动变成如下:
4.
publicstaticvoidmain(String[]args){
Frameframe=newFrame("HelloAWT!
");
frame.setBounds(200,200,300,300);
GridLayoutlayout=newGridLayout(4,3);
frame.setLayout(layout);
for(inti=0;i<10;i++){
Buttonbutton=newButton(i+"");
frame.add(button);
}
frame.setVisible(true);
}
GridBagLayout
功能强大,使用复杂。
与GirdLayout不同,GridBagLayout中的组件可以跨越多个网格,并可以设置网格大小互不相同,从而实现更加灵活的窗口效果。
知道有这个东东,就行了。
用到的机会很渺茫。
而且,swing中有个BoxLayout完全可以代替他,并且用法简单
做一个如下计算器:
分析:
菜单区可先去掉。
字体格式等其他格式都先不管,只要布局对就可以了。
三个区域:
1.显示区
2.操作区
3.数字区
publicstaticvoidmain(String[]args){
Frameframe=newFrame("简单的计算器");
frame.setLocation(100,100);
Panelp1=newPanel();
Panelp2=newPanel();
Panelp3=newPanel();
GridLayoutgridLayout=newGridLayout(1,3,2,2);
GridLayoutgridLayout2=newGridLayout(4,6,2,2);
TextFieldtf=newTextField(30);
p1.add(tf);
Buttonb1=newButton("Backspace");
Buttonb2=newButton("CE");
Buttonb3=newButton("C");
b1.setForeground(Color.red);
b1.setBackground(Color.blue);
p2.add(b1);
p2.add(b2);
p2.add(b3);
p2.setLayout(gridLayout);
for(inti=1;i<=24;i++){
Buttonbtn1=newButton(i+"");//如果有耐心,可以讲那些按钮上的字符手动敲进去
p3.add(btn1);
}
p3.setLayout(gridLayout2);
frame.add(p1,BorderLayout.NORTH);
frame.add(p2,BorderLayout.CENTER);
frame.add(p3,BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
}
注:
大部分的GUI不能依靠一种布局管理器搞定,而是多个结合使用。
AWT事件处理模型
问题:
前面我们的按钮对象,点击以后也不会发生什么事情。
就像我们遇到火灾没反应一样。
我是监工,你是劳动人民,监视你们劳动,如果不劳动,就抽你。
1.单位赋予我职责:
监工。
(监视劳动者是否打盹儿)
2.劳动者打了个盹
3.这个盹儿,被监工看到了
4.监工走上前去抽你
整个过程,我们可以细分一下,有几个对象:
劳动者:
事件源(EventSource)可以发生打盹儿,劳动,吃饭这些事件。
打个盹儿:
事件(Event)
监工:
事件监听器(EventListener)和事件处理器(Eventhandler)
当然,恋爱中,这里的监工可以变成你老婆,劳动者可以变成你。
事件可以变成看美女。
工作,监工就是老板,劳动者就是你;学习中,监工就是老师,你就是劳动者。
总之,这个模式符合所以的事情发生和处理过程。
所以,这个过程我们是可以抽象的:
1.注册监听器到事件源
2.事件源上发生事件(专业点:
外部动作触发事件源上的事件)
3.将事件传递给监听器(专业点:
先生成事件对象,然后将对象作为参数传递给事件监听器)
4.监听器调用相应的方法进行事件处理
我们点击按钮对象,然后进行相应的处理。
也符合上面的模式。
咱们写一个最简单的事件处理程序:
publicclassTest{
publicstaticvoidmain(String[]args){
Frameframe=newFrame("测试事件");
frame.setBounds(100,100,200,200);
Buttonbtn=newButton("点我吧");
btn.addActionListener(newTestListener());
frame.add(btn);
frame.setVisible(true);
}
}
classTestListenerimplementsActionListener{
publicvoidactionPerformed(ActionEvente){
//TODOAuto-generatedmethodstub
System.out.println("谁点我!
!
");
}
}
AWT中事件处理代码编写过程:
1.实现相应的Listener接口,定义一个监听类。
并通过重写actionPerformed方法来实现对相应事件的处理。
2.在事件源对象上通过add***Listener方法将1中定义的监听类的对象传递进来。
处理过程:
1.注册TestListener到btn
2.点击btn,触发事件,系统自动生成Event对象
3.Btn对象将Event对象传递给TestListener对象
4.TestListener对象调用他的actionPerformed方法进行相应的处理
简化理解上面过程:
1.注册事件
2.发生事件:
事件源组件发生事件
3.处理事件:
系统自动调用注册到该事件源组件的监听器相应的方法进行对应处理
事件源:
就是我们学过的Compotent组件
事件:
Event,它是由外部事件触发,由系统自动生成的。
常见的有如下事件:
低级事件:
基于具体的动作的事件。
比如:
窗口最小化、关闭、失去焦点;键盘按下、松开、单击;鼠标进入、点击、拖放等等。
ComponentEvent:
ContainerEvent:
WindowEvent:
FocusEvent:
KeyEvent:
MouseEvent:
高级事件:
不和特定动作关联,而和发生事件的对象关联。
比如:
ActionEvent:
当按钮、菜单项被单击,TextField中按回车。
ItemEvent:
当用户选中或取消某项
TextEvent:
当文本框、文本域里面的文本发生改变时触发
AdjustmentEvent:
调节事件,当滑动条上调节滑块时触发
事件和事件监听器接口关系总结:
一个组件可以添加多个监听器。
你女朋友不光监视你是不是看别的美女,也监视你钱怎么花对不对?
你可以接收你女朋友的监视,现在也接受老师我的监视。
Event常用的方法测试:
publicclassTest{
staticButtonb2=newButton("按钮二");
publicstaticvoidmain(String[]args){
Frameframe=newFrame("测试事件");
frame.setLayout(newFlowLayout());
frame.setBounds(100,100,200,200);
Buttonbtn=newButton("点我吧");
btn.addActionListener(newTestListener());
frame.add(b2);
frame.add(btn);
frame.setVisible(true);
}
}
classTestListenerimplementsActionListener{
publicvoidactionPerformed(ActionEvente){
//TODOAuto-generatedmethodstub
System.out.println(e.getActionCommand());//就是“点我吧”
System.out.println(e.getSource());//返回事件源对象
System.out.println(e.getWhen());//返回事件发生的时间
System.out.println("谁点我!
!
");
}
}
测试上面所有的事件:
WindowEvent事件
publicclassTest{
publicstaticvoidmain(String[]args){
Frameframe=newFrame("测试事件");
frame.setLayout(newFlowLayout());
frame.setBounds(100,100,200,200);
Buttonbtn=newButton("点我吧");
TextFieldfield=newTextField(20);
frame.add(btn);
frame.add(field);
frame.setVisible(true);
frame.addWindowListener(newTestListener());
}
}
classTestListenerimplementsWindowListener{
publicvoidwindowActivated(WindowEvente){
//TODOAuto-generatedmethodstub
System.out.println("窗口被激活!
");
}
publicvoidwindowClosed(WindowEvente){
//TODOAuto-generatedmethodstub
S
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第十一 awtdocx