Java龚永罡 - 答案 下载本文

《Java语言程序设计基础教程》

上机实验指导手册

1

实验一 Java环境演练

【目的】

①安装并配置Java运行开发环境;

②掌握开发Java应用程序的3个步骤:编写源文件、编译源文件和运行应用程序; ③掌握开发Java Applet程序的3个步骤:编写源文件、编译源文件和运行Java Applet程序;

④学习同时编译多个Java源文件。 【内容】

1.一个简单的应用程序

? 实验要求:

编写一个简单的Java应用程序,该程序在命令行窗口输出两行文字:“你好,很高兴学习Java”和“We are students”。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

Hello.java

public class Hello {

public static void main (String args[ ]) {

【代码1】 //命令行窗口输出\你好,很高兴学习Java\ A a=new A(); a.fA(); } } class A {

void fA() {

【代码2】 //命令行窗口输出\ } }

? 实验后的练习:

1. 编译器怎样提示丢失大括号的错误? 2. 编译器怎样提示语句丢失分号的错误? 3. 编译器怎样提示将System写成system这一错误? 4. 编译器怎样提示将String写成string这一错误?

2.一个简单的Java Applet程序 ? 实验要求:

编写一个简单的Java Applet程序,并在Java Applet中写两行文字:“这是一个Java Applet程序”和“我改变了字体”。

? 程序运行效果示例:

2

程序运行效果如下图所示:

? 程序模板:

FirstApplet.java

import java.applet.*; import java.awt.*;

public class FirstApplet extends Applet {

public void paint(Graphics g) {

g.setColor(Color.blue);

【代码1】//在Java Applet中绘制一行文字:“这是一个Java Applet 程序”

g.setColor(Color.red);

g.setFont(new Font(\宋体\

【代码2】//在Java Applet中绘制一行文字:“我改变了字体” } }

? 实验后的练习:

5. 程序中的主类如果不用public修饰,编译能通过吗? 6. 程序中的主类如果不用public修饰,程序能正确运行吗? 7. 程序将paint方法误写成Paint,编译能通过么? 8. 程序将paint方法误写成Paint,运行时能看到有关的输出信息吗?

3.联合编译

? 实验要求:

编写4个源文件:Hello.java、A.java、B.java和C.java,每个源文件只有一个类,Hello.java是一个应用程序(含有main方法),使用了A、B和C类。将4个源文件保存到同一目录中,例如:C:\\100,然后编译Hello.java。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

模板1:Hello.java

public class MainClass {

public static void main (String args[ ]) {

【代码1】 //命令行窗口输出\你好,只需编译我\ A a=new A(); a.fA(); B b=new B(); b.fB(); }

3

}

模板2 :A.java

public class A {

void fA() {

【代码2】 //命令行窗口输出\ } }

模板3 :B.java

public class B {

void fB() {

【代码3】 //命令行窗口输出\ } }

模板4 :C.java

public class C {

void fC() {

【代码4】 //命令行窗口输出\ }

}

? 实验后的练习:

9. 将Hello.java编译通过后,不断修改A.java源文件中的代码,比如,在命令

行窗口输出“我是A类”或“我被修改了”。要求每次修改A.java源文件后,单独编译A.java,然后直接运行应用程序Hello。

10. 如果需要编译某个目录下的全部Java源文件,比如C:\\1000目录,可以使

用如下命令:c:\\1000\\javac *.java

【结果】

将本次上机实验结果按照以上内容依次填写实验目标、过程、结果。

【注意事项】

① 实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。 ② 报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

4

实验二 Java基本数据类型与控制语句

【目的】

① 掌握char型数据和int型数据之间的相互转换,同时了解unicode字符表; ② 掌握使用if…else if多分支语句; ③ 使用if…else分支和while循环语句解决问题。 【内容】

1.输出希腊字母表。

? 实验要求:

编写一个Java应用程序,该程序在命令行窗口输出希腊字母表。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

GreekAlphabet.java

public class GreekAlphabet {

public static void main (String args[ ]) {

int startPosition=0,endPosition=0; char cStart='α',cEnd='ω';

【代码1】 //cStart做int型转换据运算,并将结果赋值给startPosition 【代码2】 //cEnd做int型转换运算,并将结果赋值给endPosition System.out.println(\希腊字母\\'α\\'在unicode表中的顺序位置:\ System.out.println(\希腊字母表:\ for(int i=startPosition;i<=endPosition;i++) {

char c='\\0';

【代码3】 //i做char型转换运算,并将结果赋值给c System.out.print(\

if((i-startPosition+1)==0)

System.out.println(\ } } }

? 实验后的练习:

1. 将一个double型数据直接赋值给float型变量,程序编译时提示怎样的错

误?

2. 在应用程序的main方法中增加语句:

float x=0.618;

程序能编译通过么?

3. 在应用程序的main方法中增加语句:

byte y=128;

5

程序能编译通过么?

4. 在应用程序的main方法中增加语句:

int z=(byte)128;

程序输出变量z的值是多少?

2.回文数。

? 实验要求:

编写一个Java应用程序。用户从键盘输入一个1—9999之间的数,程序将判断这个数是几位数,并判断这个数是否是回文数。回文数是指将该数含有的数字逆序排列后得到的数和原数相同,例如12121、3223都是回文数。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

Number.java

import javax.swing.JOptionPane; public class Number {

public static void main(String args[]) {

int number=0,d5,d4,d3,d2,d1;

String str=JOptionPane.showInputDialog(\输入一个1至99999之间的数\ number=Integer.parseInt(str);

if(【代码1】) //判断number在1至99999之间的条件 {

【代码2】 //计算number的最高位(万位)d5 【代码3】 //计算number的千位d4 【代码4】 //计算number的百位d3 d2=number0/10; d1=number;

if(【代码5】) //判断number是5位数的条件 {

System.out.println(number+\是5位数\ if(【代码6】) //判断number是回文数的条件 {

System.out.println(number+\是回文数\ } else {

System.out.println(number+\不是回文数\ } }

else if(【代码7】) //判断number是4位数的条件 {

6

System.out.println(number+\是4位数\ if(【代码8】) //判断number是回文数的条件码 {

System.out.println(number+\是回文数\ } else {

System.out.println(number+\不是回文数\ } }

else if(【代码9】) //判断number是3位数的条件 {

System.out.println(number+\是3位数\ if(【代码10】) //判断number是回文数的条件 {

System.out.println(number+\是回文数\ } else {

System.out.println(number+\不是回文数\ } } else if(d2!=0) {

System.out.println(number+\是2位数\ if(d1==d2) {

System.out.println(number+\是回文数\ } else {

System.out.println(number+\不是回文数\ } } else if(d1!=0) {

System.out.println(number+\是1位数\ System.out.println(number+\是回文数\ } } else {

System.out.printf(\不在1至99999之间\ }

7

} }

? 实验后的练习:

1. 程序运行时,用户从键盘输入2332,程序提示怎样的信息? 2. 程序运行时,用户从键盘输入654321,程序提示怎样的信息? 3. 程序运行时,用户从键盘输入33321,程序提示怎样的信息?

3.猜数字游戏。

? 实验要求:

编写一个Java应用程序,实现下列功能:

1) 程序随机分配给客户一个1—100之间的整数 2) 用户在输入对话框中输入自己的猜测

3) 程序返回提示信息,提示信息分别是:“猜大了”、“猜小了”和“猜对

了”。

4) 用户可根据提示信息再次输入猜测,直到提示信息是“猜对了”。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

GuessNumber.java

import javax.swing.JOptionPane; public class GuessNumber {

public static void main (String args[ ]) {

System.out.println(\给你一个1至100之间的整数,请猜测这个数\ int realNumber=(int)(Math.random()*100)+1; int yourGuess=0;

String str=JOptionPane.showInputDialog(\输入您的猜测:\ yourGuess=Integer.parseInt(str); while(【代码1】) //循环条件 {

if(【代码2】) //条件代码 {

str=JOptionPane.showInputDialog(\猜大了,再输入你的猜测:\ yourGuess=Integer.parseInt(str); }

else if(【代码3】) //条件代码 {

str=JOptionPane.showInputDialog(\猜小了,再输入你的猜测:\ yourGuess=Integer.parseInt(str); } }

System.out.println(\猜对了!\ }

8

}

? 实验后的练习:

1. 用“yourGuess>realNumber”替换【代码1】,可以么?

2. 语句:“System.out.println(“猜对了!”);”为何要放在while循环语句之后?放在while语句的循环体中合理吗?

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。

【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

9

实验三 类与对象、继承

【目的】

①使用类来封装对象的属性和功能;

②掌握类变量与实例变量,以及类方法与实例方法的区别; ③掌握使用package和import语句。 ④巩固以下概念:

子类的继承性

子类对象的创建过程 成员变量的继承与隐藏 方法的继承与重写

【内容】

1.三角形、梯形和圆形的类封装

? 实验要求:

编写一个Java应用程序,该程序中有3个类:Trangle、Leder和Circle,分别用来刻画“三角形”、“梯形”和“圆形”。具体要求如下:

a) Trangle类具有类型为double的三个边,以及周长、面积属性,Trangle类具有返回周长、面积以及修改三个边的功能。另外,Trangle类还具有一个boolean型的属性,该属性用来判断三个属能否构成一个三角形。

b) Lader类具有类型double的上底、下底、高、面积属性,具有返回面积的功能。

c) Circle类具有类型为double的半径、周长和面积属性,具有返回周长、面积的功能。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

AreaAndLength.java

class Trangle {

double sideA,sideB,sideC,area,length; boolean boo;

public Trangle(double a,double b,double c) {

【代码1】 //参数a,b,c分别赋值给sideA,sideB,sideC if(【代码2】) //a,b,c构成三角形的条件表达式 {

【代码3】 //给boo赋值。 } else {

【代码4】 //给boo赋值。 }

10

}

double getLength() {

【代码5】 //方法体,要求计算出length的值并返回 }

public double getArea() { if(boo) {

double p=(sideA+sideB+sideC)/2.0;

area=Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC)) ; return area; } else {

System.out.println(\不是一个三角形,不能计算面积\ return 0; } }

public void setABC(double a,double b,double c) {

【代码6】 //参数a,b,c分别赋值给sideA,sideB,sideC if(【代码7】) //a,b,c构成三角形的条件表达式 {

【代码8】 //给boo赋值。 } else {

【代码9】 //给boo赋值。 } } }

class Lader {

double above,bottom,height,area; Lader(double a,double b,double h) {

【代码10】 //方法体,将参数a,b,c分别赋值给above,bottom,height }

double getArea() {

【代码11】 //方法体,,要求计算出area返回 } }

11

class Circle {

double radius,area; Circle(double r) {

【代码12】 //方法体 }

double getArea() {

【代码13】 //方法体,要求计算出area返回 }

double getLength() {

【代码14】 //getArea方法体的代码,要求计算出length返回 }

void setRadius(double newRadius) {

radius=newRadius; }

double getRadius() {

return radius; } }

public class AreaAndLength {

public static void main(String args[]) {

double length,area; Circle circle=null; Trangle trangle; Lader lader;

【代码15】 //创建对象circle 【代码16】 //创建对象trangle。 【代码17】 //创建对象lader

【代码18】 // circle调用方法返回周长并赋值给length System.out.println(\圆的周长:\

【代码19】 // circle调用方法返回面积并赋值给area System.out.println(\圆的面积:\

【代码20】 // trangle调用方法返回周长并赋值给length System.out.println(\三角形的周长:\ 【代码21】 // trangle调用方法返回面积并赋值给area System.out.println(\三角形的面积:\

12

【代码22】 // lader调用方法返回面积并赋值给area System.out.println(\梯形的面积:\

【代码23】 // trangle调用方法设置三个边,要求将三个边修改为12,34,1。 【代码24】 // trangle调用方法返回面积并赋值给area System.out.println(\三角形的面积:\

【代码25】 // trangle调用方法返回周长并赋值给length System.out.println(\三角形的周长:\ } }

? 实验后的练习:

1. 程序中仅仅省略【代码15】,编译能通过吗? 2. 程序中仅仅省略【代码16】,编译能通过吗?

3. 程序中仅仅省略【代码15】,运行时出现怎样的异常提示?

4. 给Trangle类增加3个方法,分别用来返回3个边:sideA、sideB和sideC。 5. 让AreaAndLength类中的circle对象调用方法修改半径,然后输出修改后的

半径以及修改半径后的圆的面积和周长。

2.实例成员与类成员。

? 实验要求:

按程序模板的要求编写源文件,要特别注意程序的输出结果,并能正确解释输出的结果。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

Example.java

class A {

【代码1】 //声明一个float型实例变量a

【代码2】 //声明一个float型类变量b,即static变量b void setA(float a) {

【代码3】 //将参数a的值赋值给成员变量a }

void setB(float b) {

【代码4】 //将参数b的值赋值给成员变量b }

float getA() { return a; }

float getB() { return b;

13

}

void inputA() {

System.out.println(a); }

static void inputB() {

System.out.println(b); } }

public class Example {

public static void main(String args[]) {

【代码5】 //通过类名操作类变量b,并赋值100 【代码6】 //通过类名调用方法inputB() A cat=new A(); A dog=new A();

【代码7】 //cat象调用方法setA(int a)将cat的成员a的值设置为200 【代码8】 //cat调用方法setB(int b)将cat的成员b的值设置为400 【代码9】 //dog象调用方法setA(int a)将dog的成员a的值设置为150 【代码10】 //dog调用方法setB(int b)将dog的成员b的值设置为300 【代码11】 //cat调用inputA()。 【代码12】 //cat调用inputB()。 【代码13】 //dog调用inputA()。 【代码14】 //dog调用inputB()。 } }

? 实验后的练习:

1. 将inputA()方法中的

System.out.println(a); 改写为

System.out.println(a+b); 编译是否出错?为什么? 2. 将inputB()方法中的

System.out.println(b); 改写为

System.out.println(a+b); 编译是否报错?为什么?

3.使用package语句与import语句。

? 实验要求:

按实验要求使用package语句,并用import语句使用Java平台提供的包中的类以及自定义包中的类。掌握一些重要的操作步骤。

? 程序运行效果示例:

14

程序运行效果如下图所示:

? 程序模板:

模板1:

将模板1给出的Java源文件命名为SquareEquation.java,将编译后得到的字节码文件复制到c:\\1000\\tom\\jiafei目录中。 SquareEquation.java

package tom.jiafei;

public class SquareEquation {

double a,b,c; double root1,root2; boolean boo;

public SquareEquation(double a,double b,double c) {

this.a=a; this.b=b; this.c=c; if(a!=0) {

boo=true; } else {

boo=false; } }

public void getRoots() { if(boo) {

System.out.println(\是一元2次方程\ double disk=b*b-4*a*c; if(disk>=0) {

root1=(-b+Math.sqrt(disk))/(2*a); root2=(-b-Math.sqrt(disk))/(2*a);

System.out.printf(\方程的根:%f,%f\\n\ } else {

System.out.printf(\方程没有实根\\n\ }

15

} else {

System.out.println(\不是一元2次方程\ } }

public void setCoefficient(double a,double b,double c) {

this.a=a; this.b=b; this.c=c; if(a!=0) {

boo=true; } else {

boo=false; } } }

模板2:

将模板2给出的Java源程序SunRise.java保存到d:\\2000中。在编译模板2给出的Java源文件之前,要重新设置classpath。假设本地机SDK的安装目录是E:\\jdk1.5。

在命令行执行如下命令:

set classpath=e:\\jdk1.5\\jre\\lib\\rt.jar;.;c:\\1000

然后编译模板2给出的Java源程序。或用鼠标右键点击“我的电脑”,弹出快捷菜单,然后选择“属性”命令,弹出“系统属性”对话框,再单击该对话框中的“高级”选项卡,然后单击“环境变量”按钮。将classpath的值修改为:

E:\\jdk1.5\\jre\\lib\\rt.jar;.;c:\\1000

然后重新打开一个命令行窗口,编译模板2给出的Java源程序。

SunRise.java

import tom.jiafei.*; class SunRise {

public static void main(String args[ ]) {

SquareEquation equation=new SquareEquation(4,5,1); equation.getRoots();

equation.setCoefficient(-3,4,5);

16

equation.getRoots(); } }

? 实验后的练习:

假设SDK的安装目录是E:\\jdk1.5,那么Java运行系统默认classpath的值是:E:\\jdk1.5\\jre\\lib\\rt.jar;.;

其中的“”表示应用程序可以使用当前目录中的无名包类以及当前目录下的子目录中的类,子目录中的类必须有包名,而且包名要和子目录结构相对应。

因此,如果将模板2应用程序Sunrise.java的字节码文件存放到d:\\5000中,并将SquareEquation.java的字节码文件存放在D:\\5000\\tom\\jiafei中,那么就不需要修改classpath。要特别注意的是,因为SquareEquation.java有包名,切不可将SquareEquation.java以及它的字节码文件存放在d:\\5000中,即不可以和Sunrise.java的字节码存放在一起,请进行如下的练习: 1. 将SquareEquation.java存放在D:\\5000\\tom\\jiafei中,编译: D:\\5000\\tom\\jiafei\\javac SquareEquation.java 2. 将Sunrise.java存放到D:\\5000中,编译: D:\\5000\\javac Sunrise.java 3. 运行:

java Sunrise

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。 【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

17

实验四 字符串、时间与数字类

【目的】

①掌握String类的常用方法

②掌握Date类以及Calendar类的常用方法; ③掌握BigInteger类的常用方法。 【内容】

1.String类的常用方法。

? 实验要求:

编写一个Java应用程序,判断两个字符串是否相同,判断字符串的前缀、后缀是否和某个字符串相同,按字典顺序比较两个字符串的大小关系,检索字符串,创建字符串,将数字型字符串转换为数字,将字符串存放到数组中,用字符数组创建字符串。。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

StringExample.java

class StringExample

{ public static void main(String args[])

{ String s1=new String(\ s2=new String(\

if(【代码1】) // 使用equals方法判断s1与s2是否相同 {

System.out.println(\与s2相同\ } else {

System.out.println(\与s2不相同\ }

String s3=new String(\

if(【代码2】) //判断s3的前缀是否是“220302”。 {

System.out.println(\吉林省的身份证\ }

String s4=new String(\你\ s5=new String(\我\

if(【代码3】)//按着字典序s4大于s5的表达式。 {

System.out.println(\按字典序s4大于s5\ } else {

18

System.out.println(\按字典序s4小于s5\ }

int position=0;

String path=\

position=【代码5】 //获取path中最后出现目录分隔符号的位置 System.out.println(\中最后出现\\\\的位置:\ String fileName=【代码6】//获取path中“A.java”子字符串。 System.out.println(\中含有的文件名:\ String s6=new String(\ s7=new String(\

int n1=【代码7】 //将s6转化成int型数据。 double n2=【代码8】 //将s7转化成double型数据。 double m=n1+n2; System.out.println(m);

String s8=【代码9】 //String调用valuOf(int n)方法将m转化为字符串对象 position=s8.indexOf(\

String temp=s8.substring(position+1);

System.out.println(\数字\有\位小数\ String s9=new String(\

char a[]=【代码10】 //将s8存放到数组a中。 for(int i=a.length-1;i>=0;i--) {

System.out.print(\ } } }

? 实验后的练习:

1. 程序中的s6改写成

String s6=new String(“1a12b”); 运行时提示怎样的错误?

2. 请用数组a的前3个单元创建一个字符串并输出该串。 3. 请给出获取path中“jsp”子字符串的代码。

4. 在程序的适当位置增加如下代码,注意输出的结果。

String str1=new String(“ABCABC”), str2=null, str3=null, str4=null;

str2=str1.replaceAll(“A”,”First”); str3=str2.replaceAll(“B”,”Second”); str4=str3.replaceAll(“C”,”Third”); System.out.println(str1); System.out.println(str2); System.out.println(str3); System.out.println(str4);

19

5. 可以使用Long类中的下列static方法得到整数各种进制的字符串表示: Public static String toBinaryString(long i) Public static String toOctalString(long i)

Public static String toHexString(long i) Public static String toString(long i,int p)

其中的toString(long i, int p)返回整数i的p进制表示。请在适当位置添加代码输出12345的二进制、八进制和十六进制表示。

6. 在适当位置添加代码,分别输出数字m的整数部分和小数部分。

2.比较日期的大小。

? 实验要求:

编写一个Java应用程序,用户从输入对话框输入了两个日期,程序将判断两个日期的大小关系,以及两个日期之间的间隔天数。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

DateExample

import java.util.*;

import javax.swing.JOptionPane; public class DateExample {

public static void main(String args[ ]) {

String str=JOptionPane.showInputDialog(\输入第一个日期的年份:\ int yearOne=Integer.parseInt(str);

str=JOptionPane.showInputDialog(\输入该年的月份:\ int monthOne=Integer.parseInt(str);

str=JOptionPane.showInputDialog(\输入该月份的日期:\ int dayOne=Integer.parseInt(str);

str=JOptionPane.showInputDialog(\输入第二个日期的年份:\ int yearTwo=Integer.parseInt(str);

str=JOptionPane.showInputDialog(\输入该年的月份:\ int monthTwo=Integer.parseInt(str);

str=JOptionPane.showInputDialog(\输入该月份的日期:\ int dayTwo=Integer.parseInt(str);

Calendar calendar=【代码1】 //初始化日历对象

【代码2】 //将calendar的时间设置为yearOne年monthOne月dayOne日

long timeOne=【代码3】 //calendar表示的时间转换成毫秒

【代码4】 //将calendar的时间设置为yearTwo年monthTwo月dayTwo日

long timeTwo=【代码5】 //calendar表示的时间转换成毫秒。

20

Date date1=【代码6】 // 用timeOne做参数构造date1 Date date2=【代码7】 // 用timeTwo做参数构造date2 if(date2.equals(date1)) {

System.out.println(\两个日期的年、月、日完全相同\ }

else if(date2.after(date1)) {

System.out.println(\您输入的第二个日期大于第一个日期\ }

else if(date2.before(date1)) {

System.out.println(\您输入的第二个日期小于第一个日期\ }

long days=【代码8】//计算两个日期相隔天数

System.out.println(yearOne+\年\月\日和\

+yearTwo+\年\月\相隔\天\ } }

? 实验后的练习:

1. Calendar对象可以将时间设置到年、月、日、时、分、秒。请改进上面的程序,使用户输入的两个日期包括时、分、秒。

2. 根据本程序中的一些知识,编写一个计算利息(按天计算)的程序。从输入对话框输入存款的数目和起止时间。

3.处理大整数。

? 实验要求:

编写一个Java应用程序,计算两个大整数的和、差、积和商,并计算一个大整数的因子个数(因子中不包括1和大整数本身)。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

BigintegerExample

import java.math.*; class BigIntegerExample {

public static void main(String args[])

{ BigInteger n1=new BigInteger(\ n2=new BigInteger(\ result=null;

21

result=【代码1】//n1和n2做加法运算

System.out.println(\和:\ result=【代码2】//n1和n2做减法运算

System.out.println(\差:\ result=【代码3】//n1和n2做乘法运算

System.out.println(\积:\ result=【代码4】//n1和n2做除法运算

System.out.println(\商:\ BigInteger m=new BigInteger(\ COUNT=new BigInteger(\ ONE=new BigInteger(\ TWO=new BigInteger(\

System.out.println(m.toString()+\的因子有:\

for(BigInteger i=TWO;i.compareTo(m)<0;i=i.add(ONE)) { if((n1.remainder(i).compareTo(BigInteger.ZERO))==0) { COUNT=COUNT.add(ONE);

System.out.print(\ } }

System.out.println(\

System.out.println(m.toString()+\一共有\个因子\ } }

? 实验后的练习:

1. 编写程序,计算大整数的阶乘。

2. 编写程序,计算1+2+3…的前999999999项的和。

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。 【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

22

实验五 组件与事件处理

【目的】

①学习处理ActionEvent事件;

②学习处理ItemEvent事件和paint方法; ③学习使用布局类。 【内容】

1.算术测试。

? 实验要求:

编写一个算书测试小软件,用来训练小学生的算术能力。程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确;ComputerFrame类对象负责为算术题目提供视图,比如用户可以通过ComputerFrame类对象提供的GUI界面看到题目,并通过该GUI界面给出题目的答案;MainClass是软件的主类。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

Teacher.java

public class Teacher { int numberOne,numberTwo; String operator=\ boolean right;

public int giveNumberOne(int n) { numberOne=(int)(Math.random()*n)+1; return numberOne; }

public int giveNumberTwo(int n)

{ numberTwo=(int)(Math.random()*n)+1;

return numberTwo; }

public String giveOperator() { double d=Math.random(); if(d>=0.5) operator=\ else

operator=\

return operator;

}

public boolean getRight(int answer) { if(operator.equals(\

{ if(answer==numberOne+numberTwo)

23

right=true; else

right=false;

}

else if(operator.equals(\ { if(answer==numberOne-numberTwo) right=true; else

right=false; }

return right;

}

}

ComputerFrame.java

import java.awt.*; import java.awt.event.*;

public class ComputerFrame extends Frame implements ActionListener { TextField textOne,textTwo,textResult; Button getProblem,giveAnwser; Label operatorLabel,message; Teacher teacher;

ComputerFrame(String s) { super(s);

teacher=new Teacher(); setLayout(new FlowLayout());

textOne=【代码1】 //创建textOne,其可见字符长是10 textTwo=【代码2】 //创建textTwo,其可见字符长是10 textResult=【代码3】 //创建textResult,其可见字符长是10 operatorLabel=new Label(\ message=new Label(\你还没有回答呢\ getProblem=new Button(\获取题目\ giveAnwser=new Button(\确认答案\ add(getProblem); add(textOne); add(operatorLabel); add(textTwo); add(new Label(\ add(textResult); add(giveAnwser); add(message);

textResult.requestFocus(); textOne.setEditable(false); textTwo.setEditable(false);

【代码4】//将当前窗口注册为getProblem的ActionEvent事件监视器

24

【代码5】//将当前窗口注册为giveAnwser的ActionEvent事件监视器 【代码6】//将当前窗口注册为textResult的ActionEvent事件监视器 setBounds(100,100,450,100); setVisible(true); validate();

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } } ); }

public void actionPerformed(ActionEvent e) { if(【代码7】) //判断事件源是否是getProblem { int number1=teacher.giveNumberOne(100); int number2=teacher.giveNumberTwo(100); String operator=teacher.givetOperator(); textOne.setText(\ textTwo.setText(\ operatorLabel.setText(operator); message.setText(\请回答\

textResult.setText(null);

}

if(【代码8】) //判断事件源是否是giveAnwser { String answer=textResult.getText(); try{

int result=Integer.parseInt(answer); if(teacher.getRight(result)==true) { message.setText(\你回答正确\ } else

{ message.setText(\你回答错误\ } }

catch(NumberFormatException ex)

{ message.setText(\请输入数字字符\ } }

textResult.requestFocus(); validate(); } }

MainClass.java

public class MainClass

25

{ public static void main(String args[]) { ComputerFrame frame;

frame=【代码9】//创建窗口,其标题为:算术测试 } }

? 实验后的练习:

1. 给上述程序增加测试乘、除的功能。

2.信号灯。

? 实验要求:

编写一个带有窗口的应用程序。在窗口的北面添加一个下拉列表,该下拉列表有“”、“”和“”三个选项。在窗口的中心添加一个画布,当用户在下拉列表选择某项后,画布上绘制相应的信号灯。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

SignalCanvas.java

import java.awt.*;

public class SignalCanvas extends Canvas { int red,green,yellow,x,y,r; SignalCanvas()

{ setBackground(Color.white); }

public void setRed(int r) { red=r; }

public void setGreen(int g) { green=g; }

public void setYellow(int y) { yellow=y; }

public void setPosition(int x,int y) { this.x=x; this.y=y; }

public void setRadius(int r) { this.r=r; }

public void paint(Graphics g) { if(red==1)

{ g.setColor(Color.red); }

26

else if(green==1) { g.setColor(Color.green); }

else if(yellow==1)

{ g.setColor(Color.yellow); }

g.fillOval(x,y,2*r,2*r); } }

SignalFrame.java

import java.awt.*; import java.applet.*; import java.awt.event.*;

public class SignalFrame extends Frame implements ItemListener { Choice choice;

SignalCanvas signal=null;

String itemRed=\红灯\黄灯\绿灯\ public SignalFrame()

{ choice=【代码1】 //创建choice

【代码2】 //创建choice添加itemRed 【代码3】 //创建choice添加itemYellow 【代码4】 //创建choice添加itemGreen 【代码5】 //将当前窗口注册为choice的ItemEvent事件监视器 add(choice,BorderLayout.NORTH);

try{ Class cs=Class.forName(\ signal=(SignalCanvas)cs.newInstance(); add(signal,BorderLayout.CENTER); }

catch(Exception e)

{ add(new Label(\您还没有编写SignalCanvas

\ }

setBounds(100,100,360,300); setVisible(true); validate();

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } } ); }

public void itemStateChanged(ItemEvent e)

{ String item= 【代码6】 // choice返回被选中的条目

27

int w=signal.getBounds().width; int h=signal.getBounds().height; int m=Math.min(w,h); signal.setRadius(m/6); if(item.equals(itemRed)) { if(signal!=null) { signal.setRed(1); signal.setYellow(0); signal.setGreen(0); signal.setPosition(w/3,0); signal.repaint(); } }

else if(item.equals(itemYellow)) { if(signal!=null) { signal.setRed(0); signal.setYellow(1); signal.setGreen(0);

signal.setPosition(w/3,h/3); signal.repaint(); } }

else if(item.equals(itemGreen)) { if(signal!=null) { signal.setRed(0); signal.setYellow(0); signal.setGreen(1);

signal.setPosition(w/3,2*h/3); signal.repaint(); } } } }

SignalMainClass.java

public class SignalMainClass

{ public static void main(String args[]) { SignalFrame frame; frame=new SignalFrame() ; frame.setTitle(\信号灯\ } }

? 实验后的练习:

1. 改进上述程序,在下拉列表中增加“熄灭所有灯”选项,当选中该项时,画布上绘制一个半径为0,位置是(0,0)的圆。

28

3.布局与日历。

? 实验要求:

编写一个应用程序,有一个窗口,该窗口为BorderLayout布局。窗口的中心添加一个Panel容器:pCenter,pCenter的布局是7行7列的GriderLayout布局,pCenter中放置49个标签,用来显示日历。窗口的北面添加一个Panel容器pNorth,其布局是FlowLayout布局,pNorth放置两个按钮:nextMonth和previousMonth,单击nextMonth按钮,可以显示当前月的下一月的日历;单击previousMonth按钮,可以显示当前月的上一月的日历。窗口的南面添加一个Panel容器pSouth,其布局是FlowLayout布局,pSouth中放置一个标签用来显示一些信息。

? 程序运行效果示例:

程序运行效果如下图所示:

CalendarBean.java

import java.util.Calendar; public class CalendarBean {

String day[]; int year=2005,month=0; public void setYear(int year) { this.year=year; }

public int getYear() { return year; }

public void setMonth(int month) { this.month=month; }

public int getMonth() { return month; }

public String[] getCalendar() { String a[]=new String[42]; Calendar 日历=Calendar.getInstance(); 日历.set(year,month-1,1);

int 星期几=日历.get(Calendar.DAY_OF_WEEK)-1; int day=0;

if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { day=31; }

if(month==4||month==6||month==9||month==11) { day=30; }

? 程序模板:

29

if(month==2)

{ if(((year%4==0)&&(year0!=0))||(year@0==0)) { day=29; } else

{ day=28; } }

for(int i=星期几,n=1;i<星期几+day;i++) {

a[i]=String.valueOf(n) ; n++; } return a; } }

CalendarFrame.java

import java.util.*; import java.awt.*; import java.awt.event.*; import java.applet.*;

public class CalendarFrame extends Frame implements ActionListener { Label labelDay[]=new Label[42]; Button titleName[]=new Button[7];

String name[]={\日\一\二\三\四\五\六\ Button nextMonth,previousMonth; int year=2006,month=10; CalendarBean calendar;

Label showMessage=new Label(\ public CalendarFrame() { Panel pCenter=new Panel();

【代码1】 //将pCenter的布局设置为7行7列的GridLayout 布局。 for(int i=0;i<7;i++)

{ titleName[i]=new Button(name[i]);

【代码2】//pCenter添加组件titleName[i]。 }

for(int i=0;i<42;i++) {

labelDay[i]=new Label(\ 【代码3】//pCenter添加组件labelDay[i]。 }

calendar=new CalendarBean(); calendar.setYear(year); calendar.setMonth(month);

30

String day[]=calendar.getCalendar(); for(int i=0;i<42;i++)

{ labelDay[i].setText(day[i]); }

nextMonth=new Button(\下月\ previousMonth=new Button(\上月\ nextMonth.addActionListener(this); previousMonth.addActionListener(this); Panel pNorth=new Panel(), pSouth=new Panel(); pNorth.add(previousMonth); pNorth.add(nextMonth); pSouth.add(showMessage);

showMessage.setText(\日历:\年\月\

ScrollPane scrollPane=new ScrollPane(); scrollPane.add(pCenter);

【代码4】// 窗口添加scrollPane在中心区域 【代码5】// 窗口添加pNorth 在北面区域 【代码6】// 窗口添加pSouth 在南区域。 }

public void actionPerformed(ActionEvent e) { if(e.getSource()==nextMonth) { month=month+1; if(month>12) month=1;

calendar.setMonth(month); String day[]=calendar.getCalendar(); for(int i=0;i<42;i++) { labelDay[i].setText(day[i]); } }

else if(e.getSource()==previousMonth) { month=month-1; if(month<1) month=12;

calendar.setMonth(month); String day[]=calendar.getCalendar(); for(int i=0;i<42;i++)

{ labelDay[i].setText(day[i]); } }

showMessage.setText(\日历:\年\月\

31

} }

CalendarMainClass.java

public class CalendarMainClass { public static void main(String args[])

{ CalendarFrame frame=new CalendarFrame(); frame.setBounds(100,100,360,300); frame.setVisible(true); frame.validate();

frame.addWindowListener(new java.awt.event.WindowAdapter() { windowClosing(java.awt.event.WindowEvent e)

{ System.exit(0); } } ); } }

public

void

? 实验后的练习:

1. 请在CalendarFrame类中增加一个TextField文本框,用户可以通过在文本框中输入年份来修改calendar对象的int成员year。

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。 【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

32

实验六 多线程

【目的】

①掌握使用Thread的子类创建线程; ②学习使用Thread类创建线程; ③学习处理线程同步问题。 【内容】

1.汉字打字练习。

? 实验要求:

编写一个Java应用程序,在主线程中再创建一个Frame类型的窗口,在该窗口中再创建1个线程giveWord。线程giveWord每隔2秒钟给出一个汉字,用户使用一种汉字输入法将该汉字输入到文本框中。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

WordThread.java

import java.awt.*;

public class WordThread extends Thread { char word; int k=19968; Label com;

WordThread(Label com) { this.com=com; }

public void run() { k=19968; while(true) {

word=(char)k; com.setText(\

try{ 【代码1】//调用sleep方法使得线程中断6000豪秒 }

catch(InterruptedException e){} k++;

if(k>=29968) k=19968; } } }

ThreadFrame.java

import java.awt.*; import java.awt.event.*;

public class ThreadFrame extends Frame implements ActionListener

33

{

Label wordLabel; Button button;

TextField inputText,scoreText;

【代码2】//用WordThread声明一个giveWord对象 int score=0; ThreadFrame()

{ wordLabel=new Label(\ wordLabel.setFont(new Font(\ button=new Button(\开始\ inputText=new TextField(3); scoreText=new TextField(5); scoreText.setEditable(false);

【代码3】//创建giveWord,将wordLabel传递给WordThread构造方法的参数 button.addActionListener(this); inputText.addActionListener(this); add(button,BorderLayout.NORTH); add(wordLabel,BorderLayout.CENTER); Panel southP=new Panel();

southP.add(new Label(\输入标签所显示的汉字后回车:\ southP.add(inputText); southP.add(scoreText);

add(southP,BorderLayout.SOUTH); setBounds(100,100,350,180); setVisible(true); validate();

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } } ); }

public void actionPerformed(ActionEvent e) {

if(e.getSource()==button)

{ if(!(【代码4】)) //giveWord调用方法isAlive() { giveWord=new WordThread(wordLabel); } try

{ 【代码5】//giveWord调用方法start() }

catch(Exception exe){} }

34

else if(e.getSource()==inputText)

{ if(inputText.getText().equals(wordLabel.getText())) { score++; }

scoreText.setText(\得分:\ inputText.setText(null); } } }

WordThread.java

public class ThreadWordMainClass

{ public static void main(String args[]) { new ThreadFrame(); }

? 实验后的练习:

1. 在WordThread类中增加int型的成员time,其初值为6000,将其中的【代码1】更改为线程中断time毫秒。在WordThread类增加public void setTime(int n)方法,使得WordThread线程对象可以调用该方法修改time的值。

2.旋转的行星。

? 实验要求:

编写一个应用程序,模拟月亮围绕地球旋转、地球围绕太阳旋转。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

Mycanvas.java

import java.awt.*;

public class Mycanvas extends Canvas { int r; Color c;

public void setColor(Color c) { this.c=c; }

public void setR(int r) { this.r=r; }

public void paint(Graphics g) { g.setColor(c);

g.fillOval(0,0,2*r,2*r); }

public int getR() { return r;

35

} }

Planet.java

import java.awt.*;

public class Planet extends Panel implements Runnable { 【代码1】 //用Thread类声明一个moon对象 Mycanvas yellowBall;

double pointX[]=new double[360],

pointY[]=new double[360]; //用来表示画布左上角端点坐标的数组 int w=100,h=100; int radius=30; Planet()

{ setSize(w,h); setLayout(null);

yellowBall=new Mycanvas(); yellowBall.setColor(Color.yellow); add(yellowBall);

yellowBall.setSize(12,12); yellowBall.setR(12/2); pointX[0]=0; pointY[0]=-radius;

double angle=1*Math.PI/180; //刻度为1度

for(int i=0;i<359;i++) //计算出数组中各个元素的值

{ pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i]; pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle); }

for(int i=0;i<360;i++)

{ pointX[i]=pointX[i]+w/2; //坐标平移 pointY[i]=pointY[i]+h/2; }

yellowBall.setLocation((int)pointX[0]-yellowBall.getR(),

(int)pointY[0]-yellowBall.getR());

【代码2】 //创建 moon线程,当前面板做为该线程的目标对象 }

public void start() { try{ moon .start(); }

catch(Exception exe){} }

public void paint(Graphics g) { g.setColor(Color.blue); g.fillOval(w/2-9,h/2-9,18,18); }

public void run()

36

{ int i=0; while(true) { i=(i+1)60;

yellowBall.setLocation((int)pointX[i]-yellowBall.getR(),

(int)pointY[i]-yellowBall.getR());

try{ 【代码3】 // Thread类调用类方法sleep使得线程中断10豪秒 }

catch(InterruptedException e){} } } }

HaveThreadFrame.java

import java.awt.*; import java.awt.event.*;

public class HaveThreadFrame extends Frame implements Runnable { 【代码4】 //用Thread类声明一个rotate对象 Planet earth;

double pointX[]=new double[360], pointY[]=new double[360]; int width,height; int radius=120; HaveThreadFrame()

{ rotate=new Thread(this); earth=new Planet(); setBounds(0,0,360,400); width=getBounds().width; height=getBounds().height; pointX[0]=0; pointY[0]=-radius;

double angle=1*Math.PI/180; for(int i=0;i<359;i++)

{ pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i]; pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle); }

for(int i=0;i<360;i++) { pointX[i]=pointX[i]+width/2; pointY[i]=pointY[i]+height/2; }

setLayout(null); setVisible(true); validate();

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0);

37

} } ); add(earth);

earth.setLocation((int)pointX[0]-earth.getSize().width/2, (int)pointY[0]-earth.getSize().height/2); earth.start();

【代码5】 //用rotate调用start方法 }

public void run() { int i=0; while(true) { i=(i+1)60;

earth.setLocation((int)pointX[i]-earth.getSize().width/2, (int)pointY[i]-earth.getSize().height/2); try{ Thread.sleep(100); }

catch(InterruptedException e){} } }

public void paint(Graphics g) { g.setColor(Color.red);

g.fillOval(width/2-15,height/2-15,30,30); } }

HaveThreadFrame.java

public class ThreadRotateMainClass { public static void main(String args[]) { new HaveThreadFrame(); } }

? 实验后的练习:

1. 在Planet类中再增加一个Mycanvas对象greenBall和一个Thread对象Satellite,线程Satellite占有CPU资源期间可以让greenBall画布旋转。

3.双线程接力。

? 实验要求:

编写一个应用程序,除了主线程外,还有两个线程:first和second。first负责模拟一个红色的按钮从坐标(10,60)运动到(100,60);second负责模拟一个绿色的按钮从坐标(100,60)运动到(200,60)。

? 程序运行效果示例:

程序运行效果如下图所示:

38

? 程序模板:

MoveButton.java

import java.awt.*; import java.awt.event.*;

public class MoveButton extends Frame implements Runnable,ActionListener { 【代码1】//用Thread类声明first,second两个线程对象 Button redButton,greenButton,startButton; int distance=10; MoveButton()

{ 【代码2】 //创建first线程,当前窗口做为该线程的目标对象 【代码3】 //创建first线程,当前窗口做为该线程的目标对象 redButton=new Button(); greenButton=new Button();

redButton.setBackground(Color.red); greenButton.setBackground(Color.green); startButton=new Button(\ startButton.addActionListener(this); setLayout(null); add(redButton);

redButton.setBounds(10,60,15,15); add(greenButton);

greenButton.setBounds(100,60,15,15); add(startButton);

startButton.setBounds(10,100,30,30); setBounds(0,0,300,200); setVisible(true); validate();

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } } ); }

public void actionPerformed(ActionEvent e) { try{ first.start(); second.start(); }

catch(Exception exp){} }

public void run() { while(true)

{ if(【代码4】) //判断当前占有CPU资源的线程是否是first { moveComponent(redButton);

39

try{ Thread.sleep(20); }

catch(Exception exp){} }

if(【代码5】) //判断当前占有CPU资源的线程是否是second { moveComponent(greenButton); try{ Thread.sleep(10); }

catch(Exception exp){} } } }

public synchronized void moveComponent(Component b) {

if(Thread.currentThread()==first)

{ while(distance>100&&distance<=200) try{ wait(); }

catch(Exception exp){} distance=distance+1; b.setLocation(distance,60); if(distance>=100) { b.setLocation(10,60); notifyAll(); } }

if(Thread.currentThread()==second) { while(distance>=10&&distance<100) try{ wait(); }

catch(Exception exp){} distance=distance+1; b.setLocation(distance,60); if(distance>200) { distance=10;

b.setLocation(100,60); notifyAll(); } } } }

MoveButtonMainClass.java

public class MoveButtonMainClass

{ public static void main(String args[])

40

{ new MoveButton(); }

? 实验后的练习:

1. 在MoveButton类中再增加一个蓝色的按钮和一个third线程,third线程负责将这个蓝色的按钮从(200,60)运动到(300,60)。

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。 【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

41

实验七 输入输出流

【目的】

①掌握字符输入、输出流的用法; ②掌握RandomAccessFil类的使用; ③掌握ZipInputStream流的使用。 【内容】

1.学读汉字。

? 实验要求:

编写一个Java应用程序,要求如下:

(1)可以将一个由汉字字符组成的文本文件读入到程序中;

(2)单击名为“下一个汉字”的按钮,可以在一个标签中显示程序读入的一个汉字;

(3)单击名为“发音”的按钮,可以听到标签上显示的汉字的读音。 (4)用户可以使用文本编辑器编辑程序中用到的3个由汉字字符组成的文本文件:training1.txt、training2.txt和training.txt,这些文本文件中的汉字需要用空格、逗号或回车分隔。

()需要自己制作相应的声音文件,比如:training1.txt文件包含汉字“你”,那么在当前应用程序的运行目录中需要有“你.wav”格式的声音文件。

()用户选择“帮助”菜单,可以查看软件的帮助信息。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

ChineseCharacters.java

import java.io.*;

import java.util.StringTokenizer; public class ChineseCharacters

{ public StringBuffer getChinesecharacters(File file) { StringBuffer hanzi=new StringBuffer();

try{ FileReader inOne=【代码1】 //创建指向文件f的inOne 的对象 BufferedReader inTwo=【代码2】//创建指向文件inOne的inTwo的对象 String s=null; int i=0;

while((s=【代码3】)!=null) //inTwo读取一行 { StringTokenizer tokenizer=new StringTokenizer(s,\ while(tokenizer.hasMoreTokens()) { hanzi.append(tokenizer.nextToken()); } } }

catch(Exception e) {}

42

return hanzi; } }

StudyFrame.java

import java.awt.*; import java.awt.event.*; import java.io.*;

import javax.sound.sampled.*; public

class

StudyFrame

extends

Frame

ItemListener,ActionListener,Runnable

{ ChineseCharacters chinese; Choice choice;

Button getCharacters,voiceCharacters; Label showCharacters;

StringBuffer trainedChinese=null; Clip clip=null; Thread voiceThread; int k=0; Panel pCenter; CardLayout mycard; TextArea textHelp; MenuBar menubar; Menu menu; MenuItem help; public StudyFrame()

{ chinese=new ChineseCharacters(); choice=new Choice();

choice.add(\ choice.add(\ choice.add(\

showCharacters=new Label(\

showCharacters.setFont(new Font(\宋体\ showCharacters.setBackground(Color.green); getCharacters=new Button(\下一个汉字\ voiceCharacters=new Button(\发音\ voiceThread=new Thread(this); choice.addItemListener(this);

voiceCharacters.addActionListener(this); getCharacters.addActionListener(this); Panel pNorth=new Panel();

pNorth.add(new Label(\选择一个汉字字符组成的文件\ pNorth.add(choice);

add(pNorth,BorderLayout.NORTH); Panel pSouth=new Panel();

43

implements

pSouth.add(getCharacters); pSouth.add(voiceCharacters); add(pSouth,BorderLayout.SOUTH); pCenter=new Panel(); mycard=new CardLayout(); pCenter.setLayout(mycard); textHelp=new TextArea();

pCenter.add(\ pCenter.add(\ add(pCenter,BorderLayout.CENTER); menubar=new MenuBar(); menu=new Menu(\帮助\ help=new MenuItem(\关于学汉字\ help.addActionListener(this); menu.add(help); menubar.add(menu); setMenuBar(menubar); setSize(350,220); setVisible(true);

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } }); validate(); }

public void itemStateChanged(ItemEvent e) { String fileName=choice.getSelectedItem(); File file=new File(fileName);

trainedChinese=chinese.getChinesecharacters(file); k=0;

mycard.show(pCenter,\ }

public void actionPerformed(ActionEvent e) { if(e.getSource()==getCharacters) { if(trainedChinese!=null)

{ char c=trainedChinese.charAt(k); k++;

if(k>=trainedChinese.length()) k=0;

showCharacters.setText(\ } else

{ showCharacters.setText(\请选择一个汉字字符文件\

44

} }

if(e.getSource()==voiceCharacters) { if(!(voiceThread.isAlive())) { voiceThread=new Thread(this); }

try{ voiceThread.start(); }

catch(Exception exp){} }

if(e.getSource()==help)

{ mycard.show(pCenter,\

try{ File helpFile=new File(\

FileReader inOne=【代码4】 //创建指向文件helpFile的inOne 的对象

BufferedReader inTwo=【代码5】 //创建指向文件inOne的inTwo 的对象

String s=null;

while((s=inTwo.readLine())!=null) { textHelp.append(s+\ }

inOne.close(); inTwo.close(); }

catch(IOException exp){} } }

public void run()

{ voiceCharacters.setEnabled(false); try{ if(clip!=null) { clip.close() }

clip=AudioSystem.getClip(); File

File(showCharacters.getText().trim()+\

clip.open(AudioSystem.getAudioInputStream(voiceFile)); }

catch(Exception exp){} clip.start();

voiceCharacters.setEnabled(true); } }

voiceFile=new

StudyMainClass.java

public class StudyMainClass

45

{ public static void main(String args[]) { new StudyFrame(); } }

? 实验后的练习:

1. 在StudyFrame类中增加一个按钮previousButton,单击该按钮可以读取前一个汉字。

2.统计英文单词。

? 实验要求:

使用RandomAccessFile流统计一篇英文中的单词,要求如下: (1)一共出现了多少个单词; (2)有多少个互不相同的单词;

(3)给出每个单词出现的频率,并将这些单词按频率大小顺序显示在一个TextArea中。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

WordStatistic.java

import java.io.*; import java.util.Vector; public class WordStatistic { Vector allWorsd,noSameWord; WordStatistic()

{ allWorsd=new Vector(); noSameWord=new Vector(); }

public void wordStatistic(File file)

{ try{ RandomAccessFile inOne=【代码1】 //创建指向文件file的inOne 的对象

RandomAccessFile inTwo=【代码2】 //创建指向文件file的inTwo 的对象

long wordStarPostion=0,wordEndPostion=0; long length=inOne.length(); int flag=1; int c=-1;

for(int k=0;k<=length;k++)

{ c=【代码3】 // inOne调用read()方法 boolean boo=(c<='Z'&&c>='A')||(c<='z'&&c>='a'); if(boo) { if(flag==1)

{ wordStarPostion=inOne.getFilePointer()-1;

46

flag=0; } } else { if(flag==0) {

if(c==-1)

wordEndPostion=inOne.getFilePointer(); else

wordEndPostion=inOne.getFilePointer()-1; 【代码4】// inTwo调用seek方法将读写位置移动到wordStarPostion

byte

byte[(int)wordEndPostion-(int)wordStarPostion];

【代码5】// inTwo调用readFully(byte a)方法,向a传递cc

String word=new String(cc); allWorsd.add(word);

if(!(noSameWord.contains(word))) noSameWord.add(word); } flag=1; } }

inOne.close(); inTwo.close(); }

catch(Exception e){} }

public Vector getAllWorsd() { return allWorsd; }

public Vector getNoSameWord() { return noSameWord; } }

cc[]=new

RandomExample.java

import java.awt.*; import java.awt.event.*; import java.util.Vector; import java.io.File;

public class StatisticFrame extends Frame implements ActionListener { WordStatistic statistic;

47

TextArea showMessage; Button openFile;

FileDialog openFileDialog; Vector allWord,noSameWord; public StatisticFrame()

{ statistic=new WordStatistic(); showMessage=new TextArea(); openFile=new Button(\ openFile.addActionListener(this); add(openFile,BorderLayout.NORTH); add(showMessage,BorderLayout.CENTER);

openFileDialog=new FileDialog(this,\打开文件话框\ allWord=new Vector(); noSameWord=new Vector(); setSize(350,300); setVisible(true);

addWindowListener(new WindowAdapter()

{ public void windowClosing(WindowEvent e) { System.exit(0); } }); validate(); }

public void actionPerformed(ActionEvent e) { noSameWord.clear(); allWord.clear(); showMessage.setText(null); openFileDialog.setVisible(true);

String fileName=openFileDialog.getFile(); if(fileName!=null)

{ statistic.wordStatistic(new File(fileName)); allWord=statistic.getAllWorsd(); noSameWord=statistic.getNoSameWord();

showMessage.append(\中有\个英文单词\

showMessage.append(\其中有\个互不相同英文单词\

showMessage.append(\按使用频率排列:\\n\ int count[]=new int[noSameWord.size()]; for(int i=0;i

{ String s1=(String)noSameWord.elementAt(i); for(int j=0;j

{ String s2=(String)allWord.elementAt(j); if(s1.equals(s2))

48

count[i]++; } }

for(int m=0;mcount[m])

{ String temp=(String)noSameWord.elementAt(m);

noSameWord.setElementAt((String)noSameWord.elementAt(n),m); noSameWord.setElementAt(temp,n); int t=count[m]; count[m]=count[n]; count[n]=t; } } }

for(int m=0;m

{ showMessage.append(\ \ \ } } } }

RandomExample.java

public class StatisticMainClass

{ public static void main(String args[]) { new StatisticFrame(); } }

? 实验后的练习:

1. 在StatisticFrame的showMessage中增加单词按字典序排序输出的信息。

3.读取Zip文件。

? 实验要求:

读取book.zip,并将book.zip中含有的文件重新存放到当前目录中的book文件夹中,即将book.zip的内容解压到book文件夹中。

? 程序运行效果示例:

程序运行效果如下图所示:

? 程序模板:

ReadZipFile.java

import java.io.*;

49

import java.util.zip.*; public class ReadZipFile

{ public static void main(String args[]) { File f=new File(\ File dir=new File(\ byte b[]=new byte[100]; dir.mkdir(); try

{ ZipInputStream in=new ZipInputStream(new FileInputStream(f)); ZipEntry zipEntry=null;

while((zipEntry=in.getNextEntry())!=null) { File file=new File(dir,zipEntry.getName()); FileOutputStream out=new FileOutputStream(file); int n=-1;

System.out.println(file.getAbsolutePath()+\的内容:\ while((n=in.read(b,0,100))!=-1) { String str=new String(b,0,n); System.out.println(str); out.write(b,0,n); }

out.close(); }

in.close(); }

catch(IOException ee) {

System.out.println(ee); } } }

? 实验后的练习:

1. 编写一个GUI程序,提供1个对话框,用户可以使用这个对话框选择要解压缩的zip文件,设置解压后所得到的文件的存放目录。

【结果】

将本次上机实验结果按照实验要求内容依次进行,填写实验目标、过程、结果。 【注意事项】

①实验报告要求每人提交一份,使用专门的报告纸,内容写全,包括实验名称、班级、姓名、同组人,试验日期、交报告日期等。

②报告不需要填写源代码,只要将完成情况和所有练习题结果写上就可以。 【思考题】

50