??xml version="1.0" encoding="utf-8" standalone="yes"?>
上一节中的主要内Ҏ如何攄各种lgQ囑Ş界面更加丰富多彩Q但是还不能响应用户的Q何操作,要能够让囑Ş界面接收用户的操作,必ȝ各个lg加上事g处理机制。在事g处理的过E中Q主要涉及三cd象:
?Event-事gQ用户对界面操作在java语言上的描述Q以cȝ形式出现Q例如键盘操作对应的事gcLKeyEvent?BR> ?Event Source-事g源,事g发生的场所Q通常是各个lgQ例如按钮Button?BR> ?Event handler-事g处理者,接收事g对象q对其进行处理的对象
例如Q如果用L鼠标单击了按钮对象buttonQ则该按钮button是事g源,而javaq行时系l会生成ActionEventcȝ对象actionEQ该对象中描qC该单M件发生时的一些信息,然后Q事件处理者对象将接收由javaq行时系l传递过来的事g对象actionEq进行相应的处理?BR>
׃同一个事件源上可能发生多U事Ӟ因此java采取了授权处理机?Delegation Model)Q事件源可以把在其自w所有可能发生的事g分别授权l不同的事g处理者来处理。比如在Canvas对象上既可能发生鼠标事gQ也可能发生键盘事gQ该Canvas对象可以授权给事g处理者一来处理鼠标事Ӟ同时授权l事件处理者二来处理键盘事件。有时也事件处理者称为监听器Q主要原因也在于监听器时ȝ听着事g源上所有发生的事gcdQ一旦该事gcd与自己所负责处理的事件类型一_马上进行处理。授权模型把事g的处理委托给外部的处理实体进行处理,实现了将事g源和监听器分开的机制。事件处理者(监听器)通常是一个类Q该cd果要能够处理某种cd的事Ӟ必dC该事件类型相对的接口。例如例5.9中类ButtonHandler之所以能够处理ActionEvent事gQ原因在于它实现了与ActionEvent事g对应的接口ActionListener。每个事件类都有一个与之相对应的接口?BR>
事件源对象和事件处理器Q事件监听器Q分开。如下图所C?BR>
打个不太恰当的比喻,比如说有一位李先生Q李先生可能会发生很多法律纠UP可能是民事法律纠UP也可能是刑事法律U纷Q那么李先生可以请律师,他可以授权王律师负责帮他打民事法律的官司Q同时也可以授权张律师帮他打刑事法律的官司。这个请律师的过E从李先生的角度来看Q就是授权的q程Q而从王律师和张律师的角度来看Q一旦被授权Q他们就得时d李先生负责,"监听"着李先生,一旦发生民事纠U了Q王律师p马上d理,而一旦发生刑事纠U了Q张律师p马上q行处理。此时此刻,李先生就是事件源Q王律师是一个事件处理者,张律师是另外一个事件处理者,民事U纷和刑事纠U就是不同类型的事g?BR>
4. CardLayout
CardLayout布局理器能够帮助用户处理两个以x多的成员׃n同一昄I间Q它把容器分成许多层Q每层的昄I间占据整个容器的大,但是每层只允许放|一个组Ӟ当然每层都可以利用Panel来实现复杂的用户界面。牌布局理器(CardLayoutQ就象一副叠得整整齐齐的扑克牌一P?4张牌Q但是你只能看见最上面的一张牌Q每一张牌q当于牌布局理器中的每一层?BR> ?
5Q容器的嵌套
在复杂的囑Ş用户界面设计中,Z使布局更加易于理Q具有简z的整体风格Q一个包含了多个lg的容器本w也可以作ؓ一个组件加到另一个容器中去,容器中再d容器Q这样就形成了容器的嵌套。下面是一个容器嵌套的例子?BR>?
?l:
1QFrame是一个顶U窗口。Frame的缺省布局理器ؓBorderLayout?BR> 2QPanel 无法单独昄Q必L加到某个容器中?Panel 的缺省布局理器ؓFlowLayout?BR> 3Q当把Panel 作ؓ一个组件添加到某个容器中后Q该Panel 仍然可以有自q布局理器。因此,可以利用Panel 使得BorderLayout 中某个区域显C多个组Ӟ辑ֈ设计复杂用户界面的目??BR> 4Q如果采用无布局理?setLayout(null)Q则必须使用setLocation(),setSize(),setBounds(){方法手工设|组件的大小和位|,此方法会Dq_相关Q不鼓励使用?/SPAN>
布局理器主要包括:FlowLayoutQBorderLayoutQGridLayoutQCardLayoutQGridBagLayout
?
q行l果如下Q?BR>
1. FlowLayout
FlowLayout 是PanelQApplet的缺省布局理器。其lg的放|规律是从上C、从左到双行放|,如果容器_宽,W一个组件先d到容器中W一行的最左边Q后l的lg依次dC一个组件的双Q如果当前行已放|不下该lgQ则攄C一行的最左边?BR> 构造方法主要下面几U:
FlowLayout(FlowLayout.RIGHT,20,40);
/*W一个参数表C组件的寚w方式Q指lg在这一行中的位|是居中寚w、居叛_齐还是居左对齐,W二个参数是lg之间的横向间隔,W三个参数是lg之间的纵向间隔,单位是象素?/
FlowLayout(FlowLayout.LEFT);
//居左寚wQ横向间隔和U向间隔都是~省?个象?/FONT>
FlowLayout();
//~省的对齐方式居中对齐,横向间隔和纵向间隔都是缺省?个象?BR>?
q行l果如下:
当容器的大小发生变化Ӟ用FlowLayout理的组件会发生变化Q其变化规律是:lg的大不变,但是相对位置会发生变化。例如上图中有三个按钮都处于同一行,但是如果把该H口变窄Q窄到刚好能够放下一个按钮,则第二个按钮折到第二行Q第三个按钮折到第三行。按?Open"本来在按?OK"的右边,但是现在跑到了下面,所以说"lg的大不变,但是相对位置会发生变??BR>
q行l果如下:
在用BorderLayout的时候,如果容器的大发生变化,其变化规律ؓQ组件的相对位置不变Q大发生变化。例如容器变高了Q则North、South区域不变QWest、Center、East区域变高Q如果容器变宽了QWest、East区域不变QNorth、Center、South区域变宽。不一定所有的区域都有lgQ如果四周的区域QWest、East、North、South区域Q没有组Ӟ则由Center区域去补充,但是如果Center区域没有lgQ则保持I白Q其效果如下几幅图所C:
North区域~少l
North和Center区域~少lg
3. GridLayout
使容器中各个lg呈网格状布局Q^均占据容器的I间?BR>
1.2 lg和容?/FONT>
Java的图形用L面的最基本l成部分是组ӞComponentQ,lg是一个可以以囑Ş化的方式昄在屏q上q能与用戯行交互的对象Q例如一个按钮,一个标{。组件不能独立地昄出来Q必dlg攑֜一定的容器中才可以昄出来?/SPAN>
cjava.awt.Component是许多组件类的父c,ComponentcM装了组仉用的方法和属性,如图形的lg对象、大、显CZ|、前景色和背景色、边界、可见性等Q因此许多组件类也就l承了Componentcȝ成员Ҏ和成员变量,相应的成员方法包括:
getComponentAt(int x, int y)
getFont()
getForeground()
getName()
getSize()
paint(Graphics g)
repaint()
update()
setVisible(boolean b)
setSize(Dimension d)
setName(String name){?/FONT>
容器(Container)也是一个类Q实际上是Component的子c,因此容器本n也是一个组Ӟhlg的所有性质Q但是它的主要功能是容纳其它lg和容器?BR>
布局理器(LayoutManagerQ:每个容器都有一个布局理器,当容器需要对某个lgq行定位或判断其大小寸Ӟ׃调用其对应的布局理器?BR>
Z使我们生成的囑Ş用户界面h良好的^台无x,Java语言中,提供了布局理器这个工h理lg在容器中的布局Q而不使用直接讄lg位置和大的方式?/FONT>
在程序中安排lg的位|和大小Ӟ应该注意以下两点Q?BR> 1Q容器中的布局理器负责各个组件的大小和位|,因此用户无法在这U情况下讄lg的这些属性。如果试图用Java 语言提供的setLocation()QsetSize()QsetBounds() {方法,则都会被布局理器覆盖?
2Q如果用L实需要亲自设|组件大或位置Q则应取消该容器的布局理器,Ҏ为:
setLayout(null)Q?/SPAN>
1.3 常用容器
容器java.awt.Container是Component的子c,一个容器可以容U_个组Ӟq它们成ؓ一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面。所有的容器都可以通过add()Ҏ向容器中dlg?BR>有三U类型的容器QWindow、Panel、ScrollPaneQ常用的有Panel, Frame, Applet?BR>1QFrame
以下是容器的例子Q?BR>?