📄 jv0502.htm
字号:
26: p3.add(new Checkbox("Apple "));<br>
27: p3.add(new Checkbox("orange "));<br>
28: p3.add(new Checkbox("Strawberry "));<br>
29: p3.add(new Checkbox("Peach "));<br>
30: Panel p4 = new Panel();<br>
31: add(p4);<br>
32: p4.add(new Label("How much do you eat them per week: "));<br>
33: Choice c = new Choice();<br>
34: c.addItem("less than 1kg ");<br>
35: c.addItem("1kg to 3kg");<br>
36: c.addItem("more than 3kg");<br>
37: p4.add(c);<br>
38: Panel p5 = new Panel();<br>
39: add(p5);<br>
40: p5.add(new Label("What's your opnion of eating fruit: "));<br>
41: add(new TextArea("I think ",3,60));<br>
42: Panel p6 = new Panel();<br>
43: add(p6);<br>
44: p6.add(new Button(" OK "));<br>
45: p6.add(new Button("Clear "));<br>
46: }<br>
47: }</p>
<p> <IMG height=252
src="tu5-13.gif" width=330></p>
<p> 图5-13 嵌套的例子<br>
在这个程序中,加入了若干个Panel类,在屏幕上显示在同一行中的构件都属于同一个Panel。原来程序中没有设置版面,但是缺省是FlowLayout,排列方式缺省是居中。现在版面仍是FlowLayout,排列方式改成靠左。图5-13是执行后的结果。在各个Panel中,也使用相同的版面。当然也可将各个Panel设置成不同的版面,这样效果会不同。通过嵌套的方法,可以设计出各式各样的屏幕效果,这个程序只是一个简单的例子。相信读者在自我实践中会有更多的收获。</p>
<p> <a name="524"></a>5.2.4 事件的处理</p>
<p> 上面这些是如何设置用户界面的版面,但用户界面还应具有一定的功能,它应能接收用户的输入,这就需要处理UI构件的动作。UI构件动作的处理方法与上一章介绍的事件处理相似,不同的是UI构件所产生的特殊事件由一个专门的action方法来处理。我们所要做的就是覆盖这个方法。action方法的调用方式如下:<br>
public boolean action(Event evt, Object arg) {<br>
………<br>
}<br>
action方法的调用方式也与事件处理相似,evt参数代表这个事件,所不同的是arg参数可以是任何类型。这个参数的类型由触发这个事件的构件所决定,当一个构件触发一个事件时,这个参数用来传递一些额外的信息,所以在调用action方法时要使用这个参数。除了Label以外(Label不需要处理动作),其它构件都有不同的动作和不同的参数。按钮(Button)在被选中时产生动作,arg参数是按钮的标识。复选框(Checkbox)当一个条目被选中时产生动作,arg参数始终是true。选择菜单(Choice)当条目被选中时产生动作,arg参数代表那个条目。单行文本输入框(TextField)当用户在框内按下Return键时产生动作。与上一节关于事件的处理比较一下,就可以看出action方法可以由不同的事件触发,而类似mouseDown的方法只能由一种事件触发。所以,在action方法中判断事件的种类是不可缺少的。触发action方法的对象储存在evt参数的target实例变量中,可以使用instanceof操作符来判断对象的种类。在判断出种类之后,就可以进行处理或调用相应的处理程序。下面是使用action方法的一个例子。程序的实际长度不止这些,选出这段的目的是为了说明如何处理action方法的调用。<br>
1: import java.io.*;<br>
2: import java.awt.*;<br>
3:<br>
4: public class password extends java.applet.Applet {<br>
5: TextField t1,t2;<br>
6: Button b1,b2;<br>
7: String button;<br>
8:<br>
9: public void init() {<br>
10: setBackground(Color.white);<br>
11: setLayout (new FlowLayout());<br>
12: add(new Label("Enter your name "));<br>
13: t1 = new TextField(5);<br>
14: add(t1);<br>
15: add(new Label("Enter your password "));<br>
16: t2 = new TextField(5);<br>
17: t2.setEchoCharacter('*');<br>
18: add (t2);<br>
19: b1 = new Button(" Ok ");<br>
20: add(b1);<br>
21: b2 = new Button(" Clear ");<br>
22: add(b2);<br>
23: }<br>
24: <br>
25: public void handlebutton (String button) {<br>
26: if (button.equals(" Clear ")) {<br>
27: t1.setText("");<br>
28: t2.setText("");<br>
29: }<br>
30: <br>
31: <br>
32: public boolean action(Event evt, Object arg) {<br>
33: if (evt.target instanceof Button)<br>
34: handlebutton ((String)arg);<br>
35: return true;<br>
36: }<br>
37: }<br>
这段程序是用来让用户输入密码。12-18行是添加两个单行文本输入框,用来输入用户的姓名和密码。17行的setEchoCharacter方法设置会显字符,在介绍单行文本输入框时提到过。19-22行添加两个按钮,分别是“OK”和“Clear”,其中“Clear”按钮用于清除用户已有的输入。32-36行是action方法,当按钮按下调用action方法时,就调用handlebutton方法。25-28行是handlebutton方法,这里使用String类中的equals方法来判断两个字符串是否相同,当按下是“Clear”时,就将两分单行文本输入框中的文字清除。如果AWT构件是嵌套使用的话,动作的处理就更加复杂了。所有构件组成的嵌套树对确定事件的处理顺序是相当重要的。在这一章中接触到的事件处理方法,都是需要返回一个布尔值。相应的根据返回的布尔值,事件处理就可以分作两类。一类是接收并处理事件,然后返回true,这个事件就不再传递。另一类是接收并处理事件,然后返回false,这个事件将传递给上一层的事件处理方法。所以一旦事件发生,handleEvent方法仍然负责事件的处理。它先将这个事件传递到事件发生所在的最低层的处理方法。如果这个方法返回是true,那么就结束对这个事件的处理。如果这个方法返回是false,那么就将这个事件传递到上一层包含它的包容器的处理方法中。依此类推直到有方法对其作出处理。</p>
<p> <a name="525"></a>5.2.5 窗口构造构件</p>
<p> 窗口构造构件也是UI元素的一部分。这里将它们独立出来的原因是因为窗口构造构件既可以用在Applet中,又可以用在Application中,而前面介绍的UI元素在Applet中使用较多。下面将逐一介绍窗口构造构件。<br>
1. 框架(Frame)<br>
框架(Frame)是带标题的顶层窗口。从类的层次上来看,它和Panel都属于Container类。所以,在每个Frame中都可以设置版面,缺省是BorderLayout。Frame类的构造方法有两种。<br>
Frame()构造一个没有标题的窗口。<br>
Frame(String title)构造一个给定标题的窗口。<br>
需要说明的是,用这两个方法创建的窗口都是非可视窗口,只有使用Frame类的父类Windows类中的show方法后,才能在屏幕上显示出来。设置窗口的大小可以使用resize方法。下面是一个简单的例子。<br>
Frame window = new Frame("A Test Window");<br>
window.resize(250,150);<br>
window.show();<br>
图5-14是执行后的结果。</p>
<p> <IMG height=150 src="tu5-14.gif"
width=251></p>
<p> 2. 菜单条(MenuBar)<br>
建立了窗口之后,就要考虑给窗口添加菜单条。在Java中这一部分是由三个类实现的,它们是MenuBar,Menu和MenuItem,分别对应菜单条、菜单和菜单项。图5-15
是它们之间的类层次。</p>
<p> <IMG height=77 src="tu5-15.gif"
width=308></p>
<p> 图5-15 Menu元素的类层次<br>
MenuBar的构造方法是MenuBar(),相当简单。在构造之后,还要将它设置成窗口的菜单条,这里要使用表5-11中介绍的setMenuBar方法。MenuBar
mb = new MenuBar();<br>
window.setMenuBar(mb);<br>
需要说明的是,MenuBar类根据Menu添加的顺序从左到右显示,并建立整数索引。而根据Windows的使用习惯,帮助菜单位于菜单条的最右边,所以如果将某个菜单设置成帮助菜单,那么它总是显示在菜单条的最右边。<br>
3. 菜单(Menu)<br>
在添加完菜单条后,并不会显示任何菜单,所以还需要在菜单条中添加菜单。菜单Menu类的构造方法有两种。<br>
Menu(String)用给定的标识构造一个菜单。<br>
Menu(String, boolean)用给定的标识构造一个菜单。如果布尔值为false,那么你释放鼠标按钮后,菜单项会消失。如果布尔值为true,那么你释放鼠标按钮后,菜单项仍将显示。这时的菜单称为tearOff菜单。在构造完后,使用MenuBar类的add方法添加到菜单条中。下面是一个简单的例子,使用前面已定义过的菜单条。<br>
Menu fm = new Menu("File");<br>
mb.add(fm);<br>
Menu help = new Menu("Help");<br>
mb.add(help);<br>
mb.setHelpMenu(help);<br>
Menu opt = new Menu("Option");<br>
mb.add(opt);<br>
下面是执行的结果。</p>
<p> <IMG height=151 src="tu5-16.gif"
width=251></p>
<p> 图5-16 带菜单的窗口<br>
在某种情况下,需要阻止用户选择某个菜单,这时可以使用disable方法使这个菜单成为不可选的,需要时还可使用enable方法使它成为可选的。<br>
4. 菜单项(MenuItem)<br>
接下来的工作是往菜单中添加内容。在菜单中可以添加不同的内容,可以是菜单项(MenuItem),可以是菜单选项(CheckboxMenuItem),可以是一个子菜单,也可以是分隔符。<br>
MenuItem类和CheckboxMenuItem类的构造方法分别是:<br>
MenuItem(String)构造一个指定标识的菜单项。<br>
CheckboxMenuItem(String)构造一个指定标识的菜单选项。<br>
子菜单的添加是直接将一个子菜单添加到母菜单中,而分隔行的添加只需要将*-*作为菜单项添加到菜单中。下面的例子是将前面的例子组合在一起:<br>
MenuBar mb = new MenuBar();<br>
window.setMenuBar(mb);<br>
Menu fm = new Menu("File");<br>
mb.add(fm);<br>
Menu help = new Menu("Help");<br>
mb.add(help);<br>
mb.setHelpMenu(help);<br>
Menu opt = new Menu("Option");<br>
mb.add(opt);<br>
opt.add(new MenuItem("Change Title"));<br>
Menu change = new Menu ("Change Color");<br>
opt.add(change);<br>
change.add(new MenuItem("Blue"));<br>
change.add(new MenuItem("Green"));<br>
change.add(new MenuItem("Red"));<br>
change.add(new MenuItem("Yellow"));<br>
opt.add(new MenuItem("-"));<br>
CheckboxMenuItem show = new CheckboxMenuItem ("Show Title");<br>
opt.add(show);<br>
图5-17是执行的结果。</p>
<p> <IMG height=151 src="tu5-17.gif"
width=283></p>
<p> 图5-17 菜单项<br>
里的disable和enable方法就是在Menu类中使用的方法,因为Menu类是MenuItem类的子类,所以Menu对象可以使用MenuItem中的方法。<br>
5. 对话框(Dialog Box)<br>
对话框与框架(Frame)有一些相似,但它一般是一个临时的窗口,主要用于显示提示信息或接收用户输入。所以,在对话框中一般不需要菜单条,也不需要改变窗口大小。此外,在对话框出现时,会禁止其它窗口的输入,直到这个对话框被关闭。对话框是由Dialog类实现的。Dialog类的构造方法有两种。Dialog(Frame,
boolean)构造一个非可视的对话框,用户可通过show方法将其变为可视的。Frame类型的参数代表对话框的拥有者,boolean类型参数用于控制对话框的工作方式。如果为true,则对话框为可视时,其它构件不能接收用户的输入。此时的对话框称为“静态”的。Dialog(Frame,
String, boolean)构造一个非可视的对话框。String类型参数作为对话框的标题,其余参数与上相同。在构造对话框之后,就可以添加其它的构件。下面是一个简单的例子。<br>
Dialog dl = new Dialog(window, "Change Title", true);<br>
dl.setLayout(new FlowLayout(FlowLayout.CENTER));<br>
TextField tf = new TextField(window.getTitle(), 25);<br>
dl.add(tf);<br>
dl.add(new Button("OK"));<br>
dl.resize(200,75);<br>
dl.show();<br>
图5-18是执行后的结果。</p>
<p> <IMG height=93 src="tu5-18.gif"
width=202></p>
<p> 图5-18 对话框<br>
6. 文件对话框(FileDialog)<br>
文件对话框是对文件进行存取时出现的对话框,它是使用当前系统提供的文件对话框。但如果在Applet中使用的话,受安全性限制,实际上是不能存取文件的,只有在Application中才能使用。文件对话框是由FileDialog类实现的,它的构造方法有两种。FileDialog(Frame,
String)构造一个读文件对话框。Frame类型参数代表文件对话框的拥有者,String类型参数作为文件对话框的标题。</p>
<p> <IMG height=281
src="tu5-19.gif" width=500></p>
<p> 图5-19 文件对话框<br>
FileDialog(Frame, String, int)构造一个文件对话框。int类型参数确定是读文件对话框还是写文件对话框,它的值可以是FileDialog.LOAD或FileDialog.SAVE。其余参数含义与上相同。同样在构造完一个文件对话框之后,它仍是非可视的,需要使用show方法使其变为可视的。下面是一个简单的例子。<br>
FileDialog fd = new FileDialog(window, "Open File", FileDialog.SAVE);<br>
fd.show();<br>
图5-19 是执行后的结果。因为是在Windows 95下执行的,所以是Windows 95风格的文件对话框。虽然对话框的标题是*Open File*,但实际上还是一个写文件对话框。<br>
7. 事件的处理<br>
这里对事件的处理方法与5.2.4中的相同,只是增加对Menu和Window的处理。Menu在它的条目被选中时产生动作,arg参数是条目的标识。在上面的例子中,我们可以要求在菜单项“Change
Title”被选中时,出现一个对话框让用户修改窗口的标题。这段程序可以写成。<br>
public boolean action (Event evt, Object arg) {<br> String label =
(String)arg;<br>
if (evt.target instanceof MenuItem) {<br>
if (label.equals("Change Title")) change();<br>
return true;<br>
}<br>
return false;<br>
}<br>
public void change() {<br>
Dialog dl = new Dialog(window, "Change Title", true);<br>
dl.setLayout(new FlowLayout(FlowLayout.CENTER));<br>
TextField tf = new TextField(window.getTitle(), 25);<br>
dl.add(tf);<br>
dl.add(new Button("OK"));<br>
dl.resize(200,75);<br>
dl.show();<br>
} <br>
对Window的事件处理是由handleEvent方法来实现的,在窗口打开、关闭、移动时会产生相应的事件,handleEvent方法根据事件的类型,调用相应的处理方法。事件的类型有WINDOW_DESTROY在窗口被关闭时产生。<br>
WINDOW_EXPOSE在窗口被设置成当前窗口时产生。 <br>
WINDOW_ICONIFY在窗口被缩小成图标时产生。<br>
WINDOW_DEICONIFY在窗口从图标放大时产生。 <br>
WINDOW_MOVED在窗口移动时产生。</p>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -