---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
AWT容器分为两类:外部容器和内部容器。其中,外部容器一般会独立存在,例如Frame类;而内部容器则会嵌套在外部容器内部使用,例如Panel类。容器的层次结构如下图所示。
其中两个最常用的容器是Frame和Panel。
— 框架(Frame):Frame是顶级窗口,可以显示标题,重置大小。
— 面板(Panel):面板提供了建立应用程序的空间。我们可以把图形元件(包括其他面板)放在一个面板上,然后把这个面板作为内部容器放在Frame等外部容器上。
容器类的常用方法包括:
add()
add(Component com)
add(Component, int index)
add(Component component, Object constraints)
add(String name, Component component),
add(Component component, Object constraints, int index)
setLayout() and getLayout()
getComponent()
getInsets()
remove and removeAll()
validate()
菜单(Menu)
菜单的开发需要使用3个类:Menu、MenuBar和MenuItem。它们的层次结构如下图所示。
(1)MenuBar
我们无法直接将菜单添加到容器的某一位置,也无法使用布局管理器对其加以控制。菜单只能被添加到菜单容器(MenuBar)中。MenuBar会被添加到Frame对象中,作为整个菜单树的根基。
Frame fr = new Frame("MenuBar");
MenuBar mb = new MenuBar();
fr.setMenuBar(mb);
fr.setSize(150,100);
fr.setVisible(true);
(2)Menu
菜单可以被添加到MenuBar中或其他Menu中。
Frame fr = new Frame("MenuBar");
MenuBar mb = new MenuBar();
fr.setMenuBar(mb);
Menu m1 = new Menu("File");
Menu m2 = new Menu("Edit");
Menu m3 = new Menu("Help");
mb.add(m1);
mb.add(m2);
mb.setHelpMenu(m3);
fr.setSize(200,200);
fr.setVisible(true);
(3)MenuItem
MenuItem是菜单树中的“叶子节点”。MenuItem通常被添加到一个Menu中。对于MenuItem对象可以添加ActionListener,使其能够完成相应的操作。
Menu m1 = new Menu("File");
MenuItem mi1 = new MenuItem("Save");
MenuItem mi2 = new MenuItem("Load");
MenuItem mi3 = new MenuItem("Quit");
m1.add(mi1);
m1.add(mi2);
m1.addSeparator();
m1.add(mi3);
MenuBar和Menu都没有必要注册监听器,只需要对MenuItem添加监听器ActionListener,完成相应的操作。
下面看一个具体的Menu实例:
import java.awt.*;
import java.awt.event.*;
public class TestMenuBar extends Frame {
MenuBar menubar=new MenuBar();
Menu fileM = new Menu("File");
Menu editM = new Menu("Edit");
Menu toolsM = new Menu("Tools");
Menu helpM = new Menu("Help");
MenuItem fileM1 = new MenuItem("New");
MenuItem fileM2 = new MenuItem("Open");
MenuItem fileM3 = new MenuItem("Save");
Menu fileM4 = new Menu("print");
MenuItem printM1 = new MenuItem("preview");
MenuItem printM2 = new MenuItem("setting");
CheckboxMenuItem fileM5 = new CheckboxMenuItem("Quit",true);
public TestMenuBar(){
menubar.add(fileM);
menubar.add(editM);
menubar.add(toolsM);
menubar.add(helpM);
fileM.add(fileM1);
fileM.add(fileM2);
fileM.add(fileM3);
fileM.add(fileM4);
fileM.addSeparator();
fileM.add(fileM5);
fileM4.add(printM1);
fileM4.add(printM2);
this.setMenuBar(menubar);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});
}
}
双缓冲技术:使用双缓冲技术将会非常方便和快速的实现对组件表面所有图形的重绘。
我们很多用Java中的g.drawImage()方法导入图像时,如果我们将当前窗口转变成非当前窗口状态,再从非当前窗口恢复到当前窗口状态,有时,某些绘制好的图像会消失,除非我们重新刷新窗口,显示才会恢复正常。此外,当我们移动窗口或者其他的窗口在上移动的时候,图像会有些闪烁。这是怎么一回事呢?这就要涉及到Canvas中的paint方法的绘图机制了。
产生这种现象的主要原因是:
1、由于在显示所绘制的图像时,调用了repaint方法。repaint方法被调用时,需要清除整个背景,然后才调用paint方法显示画面。这样,在清除背景和绘制图像的短暂时间间隔内被用户看见的就是闪烁。
2、由于paint()方法需要进行复杂的计算,图像中包含着多个图形,不同图形的复杂程度及其所需要的绘制时间不同,因此,图像中的各个像素值不能同时产生,使得图形的生成频率低于显示器的刷新频率,从而造成闪烁。
下面两种方法可以明显地消除或减弱闪烁:
1、重载update方法
当AWT接收到Canvas重新绘制的请求时,调用Canvas的update方法。默认情况下,update方法清除Canvas的背景,然后调用paint方法。重载update方法,就可以将以前在paint方法中的绘图代码包含在update方法中,从而避免每次重新绘制时将整个区域清除。
2、双缓冲技术
双缓冲技术在很多动画中被采用。主要原理是创建一幅BufferedImage图像,将每一帧画入图像,然后调用drawImage方法,将整个BufferedImage图像一次画到屏幕上去。这种方法的优点在于大部分绘制是在BufferedImage进行的。将BufferedImage绘制的图像一次绘制到屏幕上。首先通过调用new BufferedImage方法生成合适的缓冲区,然后获得在缓冲区的绘图环境(即Graphics类对象)。
综上所述,我们导入图像的思路是:不直接在paint方法中调用各种绘制方法,而是采用重载update方法及双缓冲技术,生成一个图像的缓冲区,获得该缓冲区中的绘图环境后,将该绘图环境读入内存。paint方法不再负责图像的绘制工作,即paint方法不再装入任何的图像绘制代码。我们在paint方法中,直接调用update方法,在内存缓冲区的绘图环境下进行图像的绘制工作,当所有的图像绘制工作完成后,最后将缓冲区的内容一次性地写入Canvas并在窗口中直接显示出来。这种方法很巧妙地解决了图像丢失和闪烁的问题。
AWT事件处理基本概念
若使图形界面能够接收用户的操作,我们就必须给各个组件加上事件处理机制。在事件处理的过程中,主要涉及3类对象。
— Event(事件):用户对组件的一个操作,称之为一个事件,以类的形式出现,例如,键盘操作对应的事件类是KeyEvent。
— Event Source(事件源):事件发生的场所,通常就是各个组件,例如按钮Button。
— Event Handler(事件处理者):接收事件对象并对其进行处理的对象事件处理器,通常就是某个Java类中负责处理事件的成员方法。
例如,如果用户用鼠标单击了按钮对象button,则该按钮button就是事件源,而Java运行时系统会生成ActionEvent类的对象actionEvent,该对象中描述了单击事件发生时的一些信息。然后,事件处理者对象将接收由Java运行时系统传递过来的事件对象actionEvent,并进行相应的处理。事件处理模型如下图所示。
由于同一个事件源上可能发生多种事件,因此,Java采取了授权模型(Delegation Model),事件源可以把在其自身所有可能发生的事件分别授权给不同的事件处理者来处理。比如,在Canvas对象上既可能发生鼠标事件,也可能发生键盘事件,该Canvas对象就可以授权给事件处理者1来处理鼠标事件,同时授权给事件处理者2来处理键盘事件。有时也将事件处理者称为监听器,主要原因也在于监听器时刻监听着事件源上所有发生的事件类型,一旦该事件类型与自己所负责处理的事件类型一致,就马上进行处理。授权模型把事件的处理委托给外部的处理实体进行处理,实现了将事件源和监听器分开的机制。事件处理者(监听器)通常是一个类,该类如果能够处理某种类型的事件,就必须实现与该事件类型相对的接口。例如,一个ButtonHandler类之所以能够处理ActionEvent事件,原因在于它实现了与ActionEvent事件对应的接口 ActionListener。每个事件类都有一个与之相对应的接口。
事件分类
1.按产生事件的物理操作和GUI组件的表现效果进行分类,如下图所示。
2.按事件的性质分类
java.util.EventObject类是所有事件对象的基础父类,所有事件都是由它派生出来的。AWT的相关事件继承于java.awt.AWTEvent类,这些AWT事件分为两大类:低级事件和高级事件。
(1)低级事件
低级事件是指基于组件和容器的事件,当一个组件上发生事件,如鼠标的进入、点击、拖放等,或组件的窗口开关等时,触发了组件事件。
— ComponentEvent(组件事件:组件尺寸的变化、移动);
— ContainerEvent(容器事件:组件增加、移动);
— WindowEvent(窗口事件:关闭窗口、窗口闭合、图标化);
— FocusEvent(焦点事件:焦点的获得和丢失);
— KeyEvent(键盘事件:键按下、释放);
— MouseEvent(鼠标事件:鼠标单击、移动)。
(2)高级事件(语义事件)
高级事件是基于语义的事件,它可以不和特定的动作相关联,而依赖于触发此事件的类。比如,在TextField中按Enter键会触发ActionEvent事件,滑动滚动条会触发 AdjustmentEvent事件,选中项目列表的某一条就会触发ItemEvent事件。
— ActionEvent(动作事件:按钮按下,TextField中按Enter键);
— AdjustmentEvent(调节事件:在滚动条上移动滑块以调节数值);
— ItemEvent(项目事件:选择项目,不选择“项目改变”);
— TextEvent(文本事件:文本对象改变)。
---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
详细请查看:<a href="http://edu.csdn.net/heima" target="blank">http://edu.csdn.net/heima</a>