5.1预计下列代码段的输出:
public B extends Applet{
public static void main(String[] args){
System.out.println(“I am a Java guru!”);
}
}
答:在控制台输出一行字符串(如果你是直接用浏览器打开,你将不会看到这一行输出)。
5.2在使用像Button这样的组件时,为什么实现EventListener接口对Applet类来说很重要?如果不是很清楚,可以查看Button类addActionListener方法的原型。
答:Button是属于要响应用户事件的,所以,必须要有一个捕获用户事件并进行响应的机制,在Windows叫做消息循环事件回调,而Java采用了另一套方案,这就是大名鼎鼎的事件监听机制,在事件监听机制中,必须要有事件源和监听器,事件源就是将被用户操作的组件(比如:Button),监听器就是响应用户操作的类(之所以用“类”这个词,是因为响应者可以是抽象的,不一定非要是Applet),监听器必须要继承相应的EventListener接口,必须实现相应的方法,而这些方法会根据用户的操作被JVM自动调用。这道题出得很怪,因为EventListener接口并不一定非要Applet类来实现,也可以采用匿名类的形式,我就很喜欢使用匿名类。
5.3请描述组件和容器之间的异同。
答:按Java 2的类层次结构来看,容器其实也是属于组件的(容器和组件都有同样的父类Component),而组件更多偏向于外观(look and feel)和可供用户进行操作,容器更多偏向于布局和组织组件。
另外,容器可以装下组件,也可以装下容器。而组件不能装别的组件。另外,通常组件都自带边界(Bouns)而容器都没有。
5.4修改ButtonTest applet,使得它对color数组中的每一种颜色都有一个单独的按钮,和红色关联的按钮应该以Red为标签,都以currentColor作为索引。一个更加健壮的方法是扩展Button类,在它内部变换颜色。可以在自定义Button的构造函数中给它关联一个颜色并让actionPerformed方法允许Button刷新窗体。
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
//自定义按钮
class MyButton extends Button{
Color mycolor=null;//颜色索引
public MyButton(String label,Color color){
super(label);//将文字显示在按钮上
mycolor=color;//保存颜色索引
}
public Color getColor(){
return mycolor;
}
}
public class ButtonTest4 extends Applet implements ActionListener{
private MyButton []button=new MyButton[4];//按钮
//背景色
private final Color[] bgColors={Color.RED,Color.BLUE,Color.GREEN,Color.YELLOW};
private final String[] label={"红色","蓝色","绿色","黄色"};//按钮上显示的文字
//重写Applet类的init()方法
public void init(){
//初始化四个自定义按钮
for(int i=0;i<bgColors.length;i++){
button[i]=new MyButton(label[i],bgColors[i]);//创建一个按钮对象
button[i].addActionListener(this);//注册监听
this.add(button[i]);//添加按钮到applet中
}
}
public void paint(Graphics g){
//Nothing
}
public void actionPerformed(ActionEvent e){
//如果按钮产生事件,改变窗口的背景色
MyButton mbutton=(MyButton)e.getSource();
//根据按钮的颜色索引设置窗体的背景色
this.setBackground(mbutton.getColor());
repaint();
}
}
5.5修改AudiochoiceTest applet,让它实现一个List对象来容纳声音文件的文件名。应该让List具备在任何时候多选的能力,所以应该仔细修改相应的声音控制代码。
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class AudioChoiceTest5 extends Applet implements ActionListener{
//程序中声音的名字
public final String[] AUDIO={"ping","pop","return","salvation","shuffle","squish"};
//包含上述字符串数组的下拉列表框
private List choice;
//真实的音频片段数据
private AudioClip[] clips;
//控制播放和停止的按钮
private Button playClip;
private Button loopClip;
private Button stopClip;
private Button stopAllClips;
//跟踪当前哪些音频片段在播放
private boolean[] clipsPlaying;
public void init(){
this.setBackground(new Color(48,255,0));
//构建列表框和AudioClip对象
choice=new List();
clips=new AudioClip[AUDIO.length];
clipsPlaying=new boolean[AUDIO.length];
for(int i=0;i<AUDIO.length;i++){
//为每一个选项添加一个描述的字符串
choice.add(AUDIO[i]);
//添加音频片段的路径和扩展名
clips[i]=this.getAudioClip(getCodeBase(),"audio/"+AUDIO[i]+".au");
//标志这个片段是否在播放的布尔值
clipsPlaying[i]=false;
}
//设置列表框可以多选
choice.setMultipleMode(true);
this.add(choice);
//创建播放和停止按钮
playClip=new Button("播放");
playClip.addActionListener(this);
this.add(playClip);
loopClip=new Button("循环");
loopClip.addActionListener(this);
this.add(loopClip);
stopClip=new Button("停止");
stopClip.addActionListener(this);
this.add(stopClip);
stopAllClips=new Button("全部停止");
stopAllClips.addActionListener(this);
this.add(stopAllClips);
//如果没有什么要停止的话,把"停止"按钮变灰
stopClip.setEnabled(false);
stopAllClips.setEnabled(false);
}
//停止所有音频片段的播放
public void stop(){
for(int i=0;i<AUDIO.length;i++){
if(clipsPlaying[i]){
clips[i].stop();
}
}
}
//允许用户使音频片段播放,循环播放或者停止
public void actionPerformed(ActionEvent e){
int[] clipIndex=choice.getSelectedIndexes();//获得所有选中的索引
//播放被选中的音频片段
if(e.getSource()==playClip){
for(int i=0;i<clipIndex.length;i++){
clips[clipIndex[i]].play();
clipsPlaying[clipIndex[i]]=true;
}
stopClip.setEnabled(true);
stopAllClips.setEnabled(true);
}else if(e.getSource()==stopClip){
for(int i=0;i<clipIndex.length;i++){
clips[clipIndex[i]].stop();
clipsPlaying[clipIndex[i]]=false;
}
stopClip.setEnabled(false);
stopAllClips.setEnabled(false);
//只要有一个音频片段在播放就激活"停止"按钮
for(int i=0;i<AUDIO.length;i++){
if(clipsPlaying[i]){
stopClip.setEnabled(true);
stopAllClips.setEnabled(true);
break;
}
}
}else if(e.getSource()==stopAllClips){
for(int i=0;i<AUDIO.length;i++){
if(clipsPlaying[i]){
clips[i].stop();
clipsPlaying[i]=false;
}
}
stopClip.setEnabled(false);
stopAllClips.setEnabled(false);
}else if(e.getSource()==loopClip){//循环播放被选中的音频片段
for(int i=0;i<clipIndex.length;i++){
clips[clipIndex[i]].loop();
clipsPlaying[clipIndex[i]]=true;
}
stopClip.setEnabled(true);
stopAllClips.setEnabled(true);
}
}
}
//关于声音的问题,在Windows2003下面就没有了,看来是和windows有关
5.6描述怎样用多个Panel对象来创建更精致的布局。
答:关于这个问题,需要很多的实践,一句话两句话说不太清楚,所以,大家可以自己总结啦,我就不多说了。
5.7什么是卸载不当引起的速度消耗?
答:这个问题没有找到答案呀#<_>
5.8简要描述5个按钮在给定如下几种不同的布局管理器下如何排列:FlowLayout,GridLayout,CardLayout和BoderLayout。
答:略
5.9写一个applet用Label对象显示当前日期和时间。这个applet应该有规律地刷新自己,以便日期和时间可以看起来像是连续的。
import java.applet.*;
import java.awt.*;
import java.util.*;
public class DateTest extends Applet implements Runnable{
private Label label=null;
private Date date=null;
private Thread t;
public void init(){
date=new Date();
label=new Label("当前时间是:"+date.toString());
add(label);
t=new Thread(this);//创建子线程,注意this必须要被传递
t.start();//启动线程
}
public void run(){
while(true){//死循环,让线程不停的执行
date=new Date();
label.setText("当前时间是:"+date.toString());
try{
t.sleep(1000);
}catch(Exception e){
}
}
}
}
5.10修改CharacterBuilder类,让它能读一个描述默认角色名字的applet参数。可能需要修改TextFieldPanel的构造函数或者添加一个方法来设置这个文本域的值,还需要在.html文件中添加如下的代码来添加一个参数标签:
<param name=”DefaultName” value=”Merlin”>
答:这道题我就不解答了,因为实在是很简单