Java实验指导书KT(20xx版)

时间:2024.5.14

Java实验指导书KT20xx版

HUBEI UNIVERSITY OF AUTOMOTIVE TECHNOLOGY

JAVA语言程序设计

实验指导书

齐心 翟亚红 编著 翟亚红 审核

计算机实验教学示范中心

20xx年9月

Java实验指导书KT20xx版

目录

目录 ............................................................................................................................................................................. 2

实验一 Java编程环境使用 ..................................................................................................................................... 3

实验目的 ............................................................................................................................................................. 3

实验导读 ............................................................................................................................................................. 3

实验内容 ............................................................................................................................................................. 4

实验总结 ............................................................................................................................................................. 7

实验二 Java类编程练习 ......................................................................................................................................... 8

实验目的 ............................................................................................................................................................. 8

实验导读 ............................................................................................................................................................. 8

实验内容 ........................................................................................................................................................... 10

实验总结 ........................................................................................................................................................... 21

实验三 图形用户界面设计 ................................................................................................................................... 22

实验目的 ........................................................................................................................................................... 22

实验导读 ........................................................................................................................................................... 22

实验内容 ........................................................................................................................................................... 23

实验总结 ........................................................................................................................................................... 30

实验四 Java事件处理 ........................................................................................................................................... 31

实验目的 ........................................................................................................................................................... 31

实验导读 ........................................................................................................................................................... 31

实验内容 ........................................................................................................................................................... 35

实验总结 ........................................................................................................................................................... 42

实验五 多线程程序设计 ....................................................................................................................................... 44

实验目的 ........................................................................................................................................................... 44

实验导读 ........................................................................................................................................................... 44

实验内容 ........................................................................................................................................................... 46

实验总结 ........................................................................................................................................................... 51

实验六 网络编程 ................................................................................................................................................... 52

(一)练习使用InetAddress类。对程序进行分析,写出分析结果。 ...................................................... 52

(二) 阅读下面的程序并补充完整,掌握获取URL信息的一些方法。 ................................................. 52

(三)练习使用Socket和ServerSocket进行套接字编程 ........................................................................... 53

思考:如何实现服务器同时和多个客户机的通信。 ................................................................................... 55

实验七 多媒体技术 ............................................................................................................................................... 56

练习1:利用java.applet.AudioClip实现简易声音播放器 ........................................................................... 56

练习2:使用滚动条改变背景颜色 ................................................................................................................ 58

练习3:创建电闪雷鸣的动画 ........................................................................................................................ 60

参考文献: ............................................................................................................................................................... 63

附录一 Java Code之多态 ...................................................................................................................................... 64

附录二 内部类的用法 ............................................................................................................................................. 67

附录三 和类有关的匿名类 ................................................................................................................................... 68

附录四 和接口有关的匿名类 ............................................................................................................................... 69

实验一 Java编程环境使用

实验目的

1. 掌握Java运行环境的配置

2. 掌握Java程序的编写、编译、运行等过程

3. 熟悉Java语言的基本语法和运行原理

4. 掌握Java的基本数据类型、表达式和程序控制结构

5. 熟悉Eclipse开发环境的基本使用方法

实验导读

1. Java的标准输入和输出流

java.lang.System类提供了三种有用的标准流:标准输入流(System.in)、标准输出流(System.out)和标准出错流(System.err)。通过他们可以实现数据的输入输出操作。

1) 标准输入流(System.in)

通常用于读取用户从键盘输入或用户定义的输入设备的输入。类java.util.Scanner结合System.in实现对指定数据的输入。

2) 标准输出流(System.out)

用于程序的输出,通常用来在屏幕或用户指定的输出设备上显示信息。有两种典型用法:System.out.print(data)实现在当前位置输出数据,System.out.println(data)实现换行输出数据到屏幕或用户定义的输出设备。

3) 标准出错流(System.err)

用于显示出错信息,采用System.err.print(data)或System.err.println(data)将指定的data输出到指定的输出设备,默认设备为屏幕。

2. javax.swing.JOptionPane

对话框式的输入和输出,可以提供较好的界面处理。能通过弹出一个标准对话框,来提示用户。可以通过这个性质来实现具有对话框显示效果的数据输入和输出。例如:

String str=JOptionPane.showInputDialog("输入您的猜测:");

3. java.util.Scanner

java.util.Scanner类可将文本转换成原语或字符串。Scanner对象通过next()系列方法将文本标识转换成不同类型的值。通常和标准输入流(System.in)结合,允许用户通过标准输入流读入数据。Scanner类提供的方法:nextByte()、nextshort()、nextLong()、nextDouble()、nextFloat()、nextInt()等。例如: Scanner scanner=new Scanner(System.in);

int i=scanner.netInt(); //从键盘输入一个整数

scanner.close();

4. Java Applet小应用程序

Java Applet必须由浏览器来运行,因此必须编写一个超文本文件(含有applet标记的Web页),通知浏览器来运行这个Java Applet。下面是一个简单的HTML文件,使用记事本编辑如下:

<applet code= AppletTest.class height=300 width=300>

</applet>

超文本中的标记<applet>和</applet>用于通知浏览器运行一个Java Applet,code通知浏览器运行哪个

Java Applet。code=的后面是主类的字节码文件,width和height规定了Java Applet的宽度和高度。如果如果HTML文件和字节码文件不在同一目录里,必须在HTML文件中增加选项codebase,来指定小程序中.class文件所在的目录。

实验内容

1. 设置实验环境

1) 安装JDK:下载JDK包以后,按安装向导的提示依次安装。

2) 更新环境变量:

a) 在“我的电脑”单击“属性”菜单项,进入“系统属性”对话框;

b) 选择“高级”选项页;单击“环境变量”按钮,弹出“环境变量”对话框;

c) 选择“新建系统变量”,弹出“新建系统变量”对话框,在“变量名”文本框输入“JAVA_HOME”,

在“变量值”文本框输入JDK的安装路径;

d) 编辑“系统变量”中的”path”变量的值,在“变量值”最后增加JDK安装目录下的bin目

录,例如”%JAVA_HOME%\bin; ”;

e) 在“系统变量”选项区域中查看CLASSPATH 变量,如果不存在,则新建变量CLASSPATH,

否则选中该变量,单击“编辑”按钮,在“变量值”文本框的起始位置添

加”.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;”。

3) 进入命令行控制台,分别输入“java“、“java -version“和“javac“命令,看是否能够出现正确的提

示信息(注意:配置完成后需将原来打开的命令提示符窗口关闭并重新打开运行)。

2. 简单应用程序的编写

1) 在D盘上建立javalab文件夹;

2) 打开记事本,在其中输入以下代码;

public class PrintA

{

public static void main(String arg[])

{

System.out.println(" @");

System.out.println(" @ @");

System.out.println(" @ @ @");

System.out.println(" @ @ @ @");

}

}

3) 将其保存在javalab目录下,并命名为PrintA.java;

4) 打开命令行窗口,输入:

C:\Documents and Settings\Administrator>d:

D:\>cd javalab

D:\javalab>

5) 运行:

D:\javalab>javac PrintA.java

6) 查看是否已经生成class文件;

D:\javalab>dir/w

[.] [..] PrintA.java PrintA.class

7) 运行程序查看结果是否正确。

D:\javalab>java PrintA

@

@ @

@ @ @

@ @ @ @

8) 修改PrintA.java的文件名为printa,然后重新编译会有什么结果?为什么?

9) 修改PrintA.java文件中的main方法为main1,然后重新编译并运行会有什么结果?为什么?

3. 简单Applet的编写

1) 打开记事本,在其中输入以下代码;

import java.awt.*;

import java.applet.Applet;

public class AppletTest extends Applet

{

public void init()

{

setBackground(Color.cyan);

}

public void paint(Graphics g)

{

g.setColor(Color.blue);

//在Java Applet中绘制一行文字:“这是一个Java Applet 程序”

g.drawString("这是一个Java Applet 程序",10,30);

g.setColor(Color.red);

g.setFont(new Font("宋体",Font.BOLD,36));

//在Java Applet中绘制一行文字:“我改变了字体”

g.drawString("我改变了字体",10,100);

}

}

2) 将其保存在javalab目录下,并命名为AppletTest.java;

3) 将其编译成.class文件;

4) 打开记事本,在其中输入以下代码:

<applet code= AppletTest.class height=300 width=300>

</applet>

5) 将其保存在javalab目录下,并命名为AppletTest.html;

6) 在命令行下运行:

D:\javalab>appletviewer AppletTest.html

7) 还有一种查看方式,就是直接双击AppletTest.html,直接在浏览器中查看结果。

8) 将文件中class前面的public去除后再编译运行,看看会有什么结果,为什么?

9) 如果将class文件放置在D:\classes目录下,应该怎样修改AppletTest.html文件?如果将其放

置在AppletTest.html所在文件夹的classes子目录下还可以怎样写?

4. String类的常用方法(StringExample.java)

阅读分析下面程序,把程序中的代码补充完整,并查看结果。

public class StringExample {

public static void main(String args[]) {

String s1 = new String("you are a student"),

s2 = new String("how are you");

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

{

System.out.println("s1与s2相同");

} else {

System.out.println("s1与s2不相同");

}

String s3 = new String("22030219851022024");

if (【补充代码】) // 判断s3的前缀是否是“220302”

{

System.out.println("吉林省的身份证");

}

String s4 = new String("你"), s5 = new String("我");

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

{

System.out.println("按字典序s4大于s5");

} else {

System.out.println("按字典序s4小于s5");

}

int position = 0;

String path = "c:\\java\\jsp\\A.java";

position = 【补充代码】// 获取path中最后出现\\的位置

System.out.println("c:\\java\\jsp\\A.java中最后出现\\的位置:" + position);

String fileName = 【补充代码】// 获取path中“A.java”子字符串 System.out.println("c:\\java\\jsp\\A.java中含有的文件名:" + fileName);

String s6 = new String("100"), s7 = new String("123.678"); int n1 = 【补充代码】 // 将s6转化成int型数据

double n2 = 【补充代码】 // 将s7转化成double型数据

double m = n1 + n2;

System.out.println(m);

String s8 = 【补充代码】 // String调用valuOf(double n)方法将m转化为字符串对象

position = s8.indexOf(".");

String temp = 【补充代码】 // 获取s8中小数点后面的小数

System.out.println("数字" + m + "有" + temp.length() + "位小数"); String s9 = new String("ABCDEF");

} } char a[] = 【补充代码】 // 将s9存放到数组a中 for (int i = a.length - 1; i >= 0; i--) { System.out.print(" " + a[i]); }

5. 在控制台下求两个实数的最大值(CompareTwoNumbers.java)

要求:从键盘输入任意两个实数,比较两个数字的大小,将较大的数输出。数据输入和输出用Java的标准输入流和输出流来实现。请按照代码提示编写完整程序,并查看结果。

代码提示:

import java.util.Scanner; //导入Scanner对象;

Scanner scanner = new Scanner(System.in);//实例化一个Scanner对象; number1 = scanner.nextDouble();//从键盘输入一个实数赋值给number1;

6. 猜数字游戏(GuessNumber.java)

要求:系统生成一个1至100之间的随机整数(sysNumber),利用JoptionPane对话框输入你的猜测整数(guessNumber),循环猜测两个数是否相等,如果(guessNumber>sysNumber),则提示“猜大了,再输入你的猜测:”,并重新输入新的猜测整数,如果(guessNumber<sysNumber),则提示“猜小了,再输入你的猜测:”,并重新输入新的猜测整数,直到相等控制台打印“猜对了”。请按照代码提示编写完整程序,并查看结果。

代码提示:

//生成1至100之间的随机数

int sysNumber = (int)(Math.random()*100)+1;

//输入你的猜测,注意数据类型的转换

String str = JOptionPane.showInputDialog("输入您的猜测:");

guessNumber = Integer.parseInt(str);

7. 编写Java程序(SwapMatrix.java)

要求:定义一个二维数组,并给二维数组赋值,分别打印原二维数组和行列互调后的二维数组。

123

789147369456 显示出的结果为 258

实验总结

请书写你对本次实验有哪些实质性的收获和体会,以及对本次实验有何良好的建议?

实验二 Java类编程练习

实验目的

1. 掌握类及类的声明 2. 掌握对象的定义和使用 3. 掌握接口的定义与实现

实验导读

继承、封装和多态是Java面向对象的3大特性,它们是面向对象程序开发的重要环节。继承机制的使

用可以复用一些定义好的类,减少重复代码的编写。多态机制可以动态调整对象的调用,降低对象之间的依存关系。同时为了优化继承与多态,一些类除了继承父类还可以使用接口的形式,Java中的类可以同时实现多个接口,接口被用来建立类与类之间关联的标准。

1. 类的继承(extends)

继承可以理解为现实世界中的“是一种(is-a)”关系,实现继承是通过extends关键字在声明类的时候指定其父类,其声明格式如下:

Java实验指导书KT20xx版

继承某个父类而生成新的子类不但拥有父类的变量与方法,还可以为子类添加新的成员变量和成员方法,以增强父类的功能,也就是所谓的扩展。还可以使用super关键字引用父类的方法,然后再添加新的业务代码。甚至还可以在子类中为父类的某个方法定义多个重载方法,增加该类的灵活性。 2. 访问修饰符

Java中定义了private、public、protected和默认的访问修饰符,这些修饰符控制着对类和类的成员变量以及成员方法的访问规则。另外,还可以辅助static和final关键字定义特殊规则。

Java实验指导书KT20xx版

包括任意包中的任意类以及子类。

private是私有类型的权限修饰符,使用private修饰的成员变量和成员方法,只能在本类中被使用,在子类中是不可见的,并且对其他包的类也是不可见的。

protected是保护级别的权限修饰符,它保护成员不会被其他包或非子类访问。也就是说protected修饰的成员只能被子类和同一包中定义的其他类访问。

当不添加任何权限修饰符时,编译器会使用默认权限修饰符,该修饰符的权限级别与protected类似,不同之处在于,其他包定义的子类无法访问父类默认权限修饰的成员。

3. 封装(encapsulation)

封装是指把对象的属性隐藏在对象的内部,不允许外部直接访问和修改。Java规范中的设置器和

访问器就是实现封装的标准方法,它们用于设置和获取对象的属性值。

设置器方法的命名一般以set作为方法名的前缀,以属性名作为后缀。

访问器方法的命名一般以get或is作为方法名称的前缀,以属性名作为后缀。对于boolean类型的属性,应该使用is前缀定义访问器 方法。例如:

public class Car {

private String color;

private boolean running;

public String getColor() {

return color;

}

public void setColor(String color) {

this.color = color;

}

public boolean isRunning() {

return running;

}

public void setRunning(boolean running) {

this.running = running;

}

}

4. Object类

在Java中,所有的类都直接或间接继承了java.lang.Object类,它是所有类的父类。Object类中常用的两个方法为equals()和toString()方法。任何类都可以重写Object类中的方法。

5. 对象的上转型对象

假设B类是A类的子类或间接子类,当我们用子类B创建一个对象,并把这个对象的引用放到A类的对象中时:A a = new B(); 称这个A类对象a是子类对象b的上转型对象。

? 上转对象不能操作子类新增的成员变量(失掉了这部分属性);不能使用子类新增的方法(失掉了

一些功能)。

? 上转型对象可以操作子类继承或隐藏成员变量,也可以使用子类继承的或重写的方法。

? 上转型对象操作子类继承或重写的方法时,就是通知对应的子类对象去调用这些方法。因此,如

果子类重写了父类的某个方法后,对象的上转型对象调用这个方法时,一定是调用了这个重写的方法。

? 可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属性

和功能。

6. 多态(polymophism)

多态性就是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。

当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。那么当我们把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个上转型对象,那么这个上转的对象在调用这个方法时就可能具有多种形态。多态性的实现:通过方法的重载(overloading)、覆盖(overriding)和接口来实现。

? 方法重载是Java实现面向对象的多态性机制的一种方式。同一个类中多个方法有相同的名字,不

同的参数列表,这种情况称为方法重载。返回类型不同并不足以构成方法重载。当重载方法被调用时,编译器根据参数的类型和数量来确定实际调用哪个重载方法的版本。

? 方法覆盖是Java实现多态性机制的另一种方式。在类层次结构中,如果子类中的一个方法与父类

中的方法有相同的方法名并具有相同数量和类型的参数列表,这种情况称为方法覆盖。当一个覆盖方法通过父类引用被调用,Java根据当前被引用对象的类型来决定执行哪个版本的方法。可以通过super关键字调用直属父类中被覆盖的方法版本。

参考代码:附录一 Java Code之多态。

7. 接口

接口是特殊的类,只有方法的原型,方法的实现在其子类中具体定义。Java不支持多继承性,即一个类只能有一个父类。单继承性使得Java简单,易于管理程序。为了克服单继承的缺点,Java使用了接口,一个类可以实现多个接口。

一个类通过使用关键字implements 声明自己使用一个或多个接口。如果使用多个接口,用逗号隔开接口名。如:

Java实验指导书KT20xx版

如果一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。接口只关心功能,并不关心功能的具体实现。

接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法。

参考代码:附录四 和接口有关的匿名类

8. 内部类

Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类。 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。

参考代码:附录二 内部类的用法

9. 匿名类

? 和类有关的匿名类

当使用类创建对象时,程序允许我们把类体与对象的创建组合在一起,也就是说,类创建对象时,除了构造方法还有类体,此类体被认为是该类的一个子类去掉类声明后的类体,称作匿名类。匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象。

匿名类一定是内部类,匿名类可以继承父类的方法也可以重写父类的方法,匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法。匿名类的主要用途就是向方法的参数传值。

参考代码:附录三 和类有关的匿名类

? 和接口有关的匿名类

Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了接口的类去掉类声明后的类体,称作匿名类。

参考代码:附录四 和接口有关的匿名类

实验内容

1. 对象的创建和使用

编写一个圆环类Ring的Java程序。圆环类有3个数据成员,分别是内半径innerRadius,外半径

outerRadius和颜色color,这些属性通过get和set方法进行封装。另外,圆环类中的getArea方法可以返回其面积。把程序中的代码补充完整,并查看结果。

public class Ring {

private double innerRadius;

private double outerRadius;

public String color;

public Ring(double iRadius, double oRadius, String c) {

//初始化数据成员

【补充代码…】

}

//用get和set方法封装数据成员

【补充代码…】

public double getArea() {

【补充代码…】

}

public static void main(String[] args) {

Ring ring = new Ring(5,8,"red");

System.out.println("圆环的内半径: " + ring.getInnerRadius( ));

System.out.println("圆环的外半径: " + ring.getOuterRadius( ));

System.out.println("圆环的颜色: " + ring.color);

System.out.println("圆环的面积: " + ring.getArea() + "\n");

ring.setInnerRadius(4);

【补充代码】 //设置圆环ring的外半径为6

ring.setColor("blue");

System.out.println("圆环的内半径: " + ring.getInnerRadius( ));

System.out.println("圆环的外半径: " + ring.getOuterRadius( ));

System.out.println("圆环的颜色: " + ring.color);

System.out.println("圆环的面积: " + ring.getArea());

}

}

思考:

1) 将程序中的语句Ring ring = new Ring(5,8,"red"); 改成Ring ring = new Ring();修改后

编译运行,此时有错误发生吗?分析错误的原因。

2) 接着为程序添加一个如下所示的默认构造函数,观察程序运行是否还有上述错误发生?

public Ring() {

innerRadius = 1.0;

outerRadius = 2.0;

color = "white";

}

3) 如果在输出圆环的面积时要求保留两位小数,程序如何修改?

4) 请为圆环类Ring在添两个方法以便能返回内圆和外圆的周长,然后在主函数main()中分别

创建两个对象ring1,ring2以显示周长。

2. 使用类来封装对象的属性和功能

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

Trangle类具有类型为double的三个边(sideA,sideB,sideC),以及周长(length)、面积(area)属性,Trangle类具有返回周长(getLength)、面积(getArea)以及修改三个边(setABC)的功能。另外还有一个boolean型的属性(boo),该属性用来判断三个数是否构成一个三角形。

Lader类具有类型为double的上底(above)、下底(bottom)、高(height)、面积(area)属性,具有返回面积(getArea)的功能。

Circle类具有类型为double的半径(radius)、周长(length)和面积(area)属性,具有返回周长(getLength)、面积(getArea)的功能。

把程序中的代码补充完整,并查看结果。

// Trangle .java

class Trangle

{

double sideA,sideB,sideC,area,length;

boolean boo;

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

{

//带参数的构造方法

setABC(a,b,c);

}

double getLength()

{

//方法体,要求计算出length的值并返回

【补充代码…仿照getArea()方法编写】

}

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)

{

//参数a,b,c分别赋值给sideA,sideB,sideC

【补充代码…】

if(【补充代码】) //a,b,c构成三角形的条件表达式

{

【补充代码】 //给boo赋值。

}

else

{

【补充代码】 //给boo赋值。

}

}

}

// Lader.java

class Lader

{

double above,bottom,height,area;

Lader(double a,double b,double h)

{

//带参数的构造方法,将参数a,b,h分别赋值给above,bottom,height

【补充代码…】

}

double getArea()

{

//方法体,,要求计算出area返回

【补充代码…】

}

}

// Circle.java

class Circle

{

double radius,area, length;

Circle(double r)

{

//带参数的构造方法

【补充代码】

}

double getArea()

{

//方法体,要求计算出area返回

【补充代码…】

}

double getLength()

{

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

【补充代码…】

}

void setRadius(double newRadius)

{

radius=newRadius;

}

double getRadius()

{

return radius;

}

}

// AreaAndLength.java

public class AreaAndLength

{

public static void main(String args[])

{

double length,area;

Circle circle = null;

Trangle trangle = null;

Lader lader = null;

【补充代码】 //创建对象circle(半径为5)

【补充代码】 //创建对象trangle(边长分别为3,4,5)

【补充代码】 //创建对象lader

【补充代码】 // circle调用方法返回周长并赋值给length

System.out.println("圆的周长:"+length);

【补充代码】 // circle调用方法返回面积并赋值给area

System.out.println("圆的面积:"+area);

【补充代码】 // trangle调用方法返回周长并赋值给length

System.out.println("三角形的周长:"+length);

【补充代码】 // trangle调用方法返回面积并赋值给area

System.out.println("三角形的面积:"+area);

【补充代码】 // lader调用方法返回面积并赋值给area

System.out.println("梯形的面积:"+area);

【补充代码】 // trangle调用方法设置三个边,要求将三个边修改为12,34,1。

【补充代码】 // trangle调用方法返回面积并赋值给area

System.out.println("三角形的面积:"+area);

【补充代码】 // trangle调用方法返回周长并赋值给length

System.out.println("三角形的周长:"+length);

}

}

3. 掌握上转型对象的使用,多态的特性

定义一个抽象(abstract)类,类名为Employee。 Employee的子类有YearWorker、MonthWorker和WeekWorker。YearWorker对象按年领取薪水(每年10万),MonthWorker对象按月领取薪水(每月1万),WeekWorker对象按周领取薪水(每周0.5万,设定一个月4周)。Employee类有一个抽象(abstract)方法:

public abstract double earnings();

子类必须重写父类的earnings()方法,给出各自领取每年报酬的具体方式。

有一个Company类,该类用Employee数组作为成员,Employee数组的单元可以是YearWorker对象、MonthWorker对象、WeekWorker对象的上转型对象。程序能输出Company对象一年需要支付的薪水总额。

请按模版要求,将代码补充完整。

abstract class Employee {

public abstract double earnings();

}

class YearWorker extends Employee {

【补充代码…】 //重写earnings()方法

}

class MonthWorker extends Employee {

【补充代码…】 //重写earnings()方法

}

class WeekWorker extends Employee {

【补充代码…】 //重写earnings()方法

}

class Company {

Employee[] employees;

double salaries = 0;

Company(Employee[] employees) {

this.employees = employees;

}

public double salariesPay() {

salaries = 0;

for(int i=0;i<employees.length;i++) salaries=salaries+employees[i].earnings();

return salaries;

}

}

public class HardWork {

public static void main(String[] args) {

Employee[] employees = new Employee[20];

for (int i = 0; i < employees.length; i++) { //计算salaries

} } if(i%3==0) employees[i] = new WeekWorker(); else if(i%3==1) employees[i] = new MonthWorker(); else if(i%3==2) employees[i] = new YearWorker(); } Company company = new Company(employees); System.out.println("公司年工资总额:" + company.salariesPay());

4. 掌握嵌套类和内部类的概念和用法

编写一个程序要求定义一个外部类Outer,然后在Outer类中定义一个内部类Inner和局部类Local,内部类Inner和局部类Local的任务都是显示出外部类中的数组元素,然后求出这些数组元素的平均值。

请按模版要求,将代码补充完整。

class Outer {

private int data[];

Outer(int x[]) {

data = x;

}

void checkInner() {

Inner innerObj = new Inner();

【补充代码】 // 调用Inner对象的show()方法

System.out.println("内部类计算的平均值: " + innerObj.average()); }

void checkLocal() {

class Local {

void show() {

System.out.print("从局部类显示数组元素:");

for (int i = 0; i < data.length; i++) {

System.out.print(data[i] + " ");

}

System.out.println();

}

int average() {

int sum = 0;

for (int i = 1; i < data.length; i++) {

sum += data[i];

}

【补充代码】 // 返回data数组的平均值

}

}

Local localObj = new Local();

localObj.show();

System.out.println("局部类计算的平均值: " + localObj.average()); }

class Inner {

void show() {

System.out.print("从内部类显示数组元素:");

for (int i = 0; i < data.length; i++) {

【补充代码】 // 打印data数组的每个元素

}

System.out.println();

}

int average() {

int sum = 0;

for (int i = 1; i < data.length; i++) {

sum += data[i];

}

return sum / data.length;

}

}

}

public class InnerClassTest {

public static void main(String[] args) {

int a[] = { 6, 8, 9, 22, 34, 7, 2, 1, 15 };

Outer outerObj = new Outer(a);

outerObj.checkInner();

【补充代码】 // 调用outerObj对象的checkLocal方法

}

}

5. 编写一个学生信息管理系统,掌握接口的定义方法以及类的继承、封装和多态的特性。

Java实验指导书KT20xx版

学生信息管理系统类图

1) 定义学生类Student.java,该类有学号、姓名和系部三个成员变量,并用get和set方法进行

属性的封装,请参考类图进行编写。

2) 定义接口IStudentDAO,其中包含下列数据操作方法

// 插入学生信息记录

public void insertStudent(Student stu);

// 删除指定学号学生信息记录

public void deleteStudent(String sno);

// 更新指定学生信息记录

public void updateStudent(Student stu);

// 按学号查询指定学生信息记录

public Student findStudentBySno(String sno);

// 显示指定学号学生信息记录

public void displayStudentBySno(String sno);

// 显示所有学生信息记录

public void displayAllStudent();

3) 定义接口IStudentDAO的实现类StudentDAOImpl,其中包含一个静态的集合对象用来保存学生

信息记录,以及接口的所有实现方法,请参考类图进行编写。

代码提示:

static List<Student> students = new ArrayList<Student>();

ArrayList类是实现了List接口的动态数组,数组元素可以动态增加和减少。常用方法如下: public int size()返回此列表中的元素数。

public boolean isEmpty()如果此列表中没有元素,则返回 true

public boolean add(E e)将指定的元素添加到此列表的尾部。

public boolean remove(Object o)移除此列表中首次出现的指定元素(如果存在)。 /** * 显示所有学生信息记录参考代码 */ @Override public void displayAllStudent() { if (students.size() > 0) { for (Student stu : students) { System.out.println("学号: " + stu.getSno() + "\t姓名: " + stu.getSname() + "\t系部: " + stu.getSdept()); } }else { System.out.println("数据库中无学生记录!"); } }

4) 定义主类MainClass,实现应用程序的所有逻辑功能。参考代码如下:

import java.util.Scanner;

public class MainClass {

/**

* 菜单显示

* @param scanner

* @return int

*/

static int menu_select(Scanner scanner) {

int menuchoice = -1;

System.out.printf("\n");

System.out.printf("\t\t\t 学生信息管理系统功能菜单 \n"); System.out.printf("\t\t\t 作者:齐心 \n");

System.out.printf("\t\t\t ======================= \n"); System.out.printf("\t\t\t 1.插入学生信息记录 \n"); System.out.printf("\t\t\t 2.删除学生信息记录 \n"); System.out.printf("\t\t\t 3.更新学生信息记录 \n"); System.out.printf("\t\t\t 4.显示所有学生信息记录 \n"); System.out.printf("\t\t\t 5.按学号查询指定学生信息 \n"); System.out.printf("\t\t\t 0.结束程序 \n");

System.out.printf("\t\t\t ======================= \n"); System.out.printf("\t\t\t请输入您的选择: \n");

menuchoice = scanner.nextInt();

return menuchoice;

}

/**

* 输入学生信息

* @param stu

* @param scanner */ static void inputStudent(Student stu, Scanner scanner) { System.out.println("请输入学生的学号:"); stu.setSno(scanner.next()); System.out.println("请输入学生的姓名:"); stu.setSname(scanner.next()); System.out.println("请输入学生的系部:"); stu.setSdept(scanner.next()); } /** * 更新学生信息 * @param stu * @param scanner */ static void updateStudent(Student stu, Scanner scanner) { System.out.println("请输入要更新的学生的姓名:"); stu.setSname(scanner.next()); System.out.println("请输入要更新的学生的系部:"); stu.setSdept(scanner.next()); } /** * 主函数 * @param args */ public static void main(String[] args) { String sno; int menuChoice; Scanner scanner = new Scanner(System.in); StudentDAOImpl studentDAOImpl = new StudentDAOImpl(); do { menuChoice = menu_select(scanner); switch (menuChoice) { // 插入学生信息记录 case 1: Student newStu = new Student(); inputStudent(newStu, scanner); studentDAOImpl.insertStudent(newStu); break; // 删除学生信息记录 case 2: System.out.println("请输入要删除学生信息的学号:");

入!!!");

break;

}

} while (menuChoice != 0); scanner.close();

}

} sno = scanner.next(); studentDAOImpl.deleteStudent(sno); break; // 更新学生信息记录 case 3: System.out.println("请输入要更新学生信息的学号:"); sno = scanner.next(); Student updateStu = studentDAOImpl.findStudentBySno(sno); if (updateStu != null) { System.out.println("要更新的学生信息显示如下:"); studentDAOImpl.displayStudentBySno(updateStu.getSno()); updateStudent(updateStu, scanner); studentDAOImpl.updateStudent(updateStu); } else { System.out.println("要更新的学生信息不存在!"); } break; // 显示所有学生信息记录 case 4: studentDAOImpl.displayAllStudent(); break; // 按学号查询指定学生信息 case 5: System.out.println("请输入查询学生信息的学号:"); sno = scanner.next(); studentDAOImpl.displayStudentBySno(sno); break; case 0: break; default: System.out.println("对不起,您输入的功能编号有错!请重新输

实验总结

请书写你对本次实验有哪些实质性的收获和体会,以及对本次实验有何良好的建议?

实验三 图形用户界面设计

实验目的

1. 掌握Java语言中GUI编程的基本方法

2. 掌握Java语言中AWT组件的基本用法

3. 掌握Java语言中Swing组件的基本用法

实验导读

1. 通过图形用户界面(GUI:Graphics User Interface),用户和程序之间可以方便地进行交互。 AWT(Abstract Windowing Toolkit),中文译为抽象窗口工具包,是Java提供的用来建立和设置Java的图形用户界面的基本工具。AWT由Java中的java.awt包提供,里面包含了许多可用来建立与平台无关的图形用户界面(GUI)的类,这些类又被称为组件(components)。

Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。

JDK写程序 所有功能都是靠虚拟机去操作本地操作系统。比如window下,就是JDK用windows API实现功能。而awt包中很多组件是组件自身去调用本地操作系统代码

swing包中的组件 采用的是调用本地虚拟机方法,由虚拟机再调用本地操作系统代码。意思就是中间多了一层,这样就加强了swing包的移植性,与本地关系不那强了。

图3.1 AWT常用组件继承关系图

Container为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。

2. 布局,容器中的组件的排放方式。常见的布局管理器:

FlowLayout(流式布局管理器):从左到右的顺序排列。Panel默认的布局管理器。

BorderLayout(边界布局管理器):东,南,西,北,中。Frame默认的布局管理器。 GridLayout(网格布局管理器):规则的矩阵

CardLayout(卡片布局管理器):选项卡

Java实验指导书KT20xx版

GridBagLayout(网格包布局管理器):非规则的矩阵

3. 类JFrame是java.awt.Frame 的扩展版本,该版本添加了对 JFC/Swing 组件架构的支持,常用方法

如下:

1) JFrame() 该构造方法可以创建一个无标题的窗口,窗口的默认布局为BorderLayout布局。

2) JFrame(String s) 该构造方法可以创建一个标题为s的窗口,窗口的默认布局为BorderLayout

布局。

3) public void setBounds(int a,int b,int width,int height) 窗口调用该方法可以设置出现在屏幕上时

的初始位置是(a,b),即距屏幕左面a个像素、距屏幕上方b个像素;窗口的宽是width,高是height。

4) public void setSize(int width,int height) 设置窗口的大小,窗口在屏幕出现是默认位置是(0,0)。

5) public void setVisible(boolean b) 设置窗口是可见还是不可见,窗口默认是不可见的。

6) public void setResizable(boolean b) 设置窗口是否可调整大小,窗口默认是可调整大小的。

7) public void setDefaultCloseOperation(int operation) 设置用户在此窗体上发起 "close" 时默认执

行的操作。

8) public void setLocationRelativeTo(Component c) 设置窗口相对于指定组件的位置。 如果组件当

前未显示,或者 c 为 null,则此窗口将置于屏幕的中央。

实验内容

1. 图形用户界面设计程序(ArtFont.java)

要求:设计一个文字字体设置窗体,在该窗体中可以设置要显示文字的字体内容,包括字体名称、字体大小、粗体和斜体等字体风格。并模拟在不同操作系统下的显示效果。程序的最终显示效果如下:

提示:整个窗体继承于JFrame,采用BorderLayout布局。在窗体中添加三个JPanel:northPanel、centerPanel和southPanel,分别位于窗体的北部、中部和南部,然后分别在各个面板中添加其它组件,并逐步完善程序功能。

Java实验指导书KT20xx版

请按以下步骤完成程序设计:

1) 新建ArtFont类,该类用于显示主界面。其主要代码如下:

public class ArtFont extends JFrame {

JComboBox fontType;//字体样式下拉框, JComboBox fontSize;//字体大小下拉框 JComboBox windowStyle;//窗体样式下拉框 JCheckBox boldBx;// 粗体按钮 JCheckBox italicBx;// 斜体按钮 JButton colorBtn;// 颜色按钮; String[] fontNames;// 字体名称; String[] fontSizes;// 字体大小; JLabel label;// 输入提示标签; JTextField inputText;// 文字输入框; JTextArea txtArea;// 文字显示区; JPanel northPanel;// 字体设置; JPanel centerPanel;// 显示效果区 JPanel southPanel;//样式设置 Font font; int boldStyle, italicStyle, underlineStyle; int fontSizeStyle; String fontNameStyle; Color colorStyle = Color.black;// 设置字体的默认颜色为黑色; String[] style = { "默认显示效果", "Windows显示效果", "Unix显示效果" }; public ArtFont() { super("字体设置"); // 设置默认字体 boldStyle = 0; italicStyle = 0; underlineStyle = 0; fontSizeStyle = 10;

fontNameStyle = "宋体";

font = new Font(fontNameStyle, boldStyle + italicStyle, fontSizeStyle);

northPanel = getNorthPanel();

centerPanel = getCenterPanel();

southPanel = getSouthPanel();

// 设置容器; Container container = getContentPane(); container.setLayout(new BorderLayout());

} 【补充代码】//将northPanel添加到窗体的北部 【补充代码】//将centerPanel添加到窗体的北部 【补充代码】//将southPanel添加到窗体的北部 setSize(500, 300); 【补充代码】//将窗体位于屏幕的中央 setVisible(true); } private JPanel getNorthPanel() { JPanel panel = new JPanel(); return panel; } private JPanel getCenterPanel() { JPanel panel = new JPanel(); return panel; } private JPanel getSouthPanel() { JPanel panel = new JPanel(); return panel; } public static void main(String args[]) { ArtFont artFont = new ArtFont(); artFont.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }

2) 根据ArtFont类代码和程序界面图设计北部面板northPanel: private JPanel getNorthPanel() { JPanel panel = new JPanel(); 【补充代码…】 label=new JLabel("输入"); inputText=new JTextField(10); boldBx=new JCheckBox("粗体"); italicBx=new JCheckBox("斜体"); colorBtn=new JButton("颜色"); panel.add(label); panel.add(inputText); panel.add(boldBx); panel.add(italicBx);

panel.add(colorBtn);

} return panel; 3) 根据ArtFont类代码和程序界面图设计中部面板centerPanel: private JPanel getCenterPanel() {

JPanel panel = new JPanel(); 【补充代码…】 txtArea=new JTextArea(20,80); panel.add(txtArea);

} return panel; 4) 根据ArtFont类代码和程序界面图设计南部面板southPanel: private JPanel getSouthPanel() { JPanel panel = new JPanel();

//获得系统默认字体

GraphicsEnvironment ge =

GraphicsEnvironment.getLocalGraphicsEnvironment();

fontNames = ge.getAvailableFontFamilyNames();

fontType = new JComboBox(fontNames);

//设置字体大小 fontSizes = new String[63]; for (int i = 0; i < fontSizes.length; i++) { fontSizes[i] = Integer.toString(i+10); } 【补充代码…】 fontSize=new JComboBox(fontSizes); windowStyle=new JComboBox(style);//窗体样式下拉框 panel.add(fontType); panel.add(fontSize); panel.add(windowStyle);

} return panel;

5) 调试、编译和运行程序,并显示正确界面。

2. 日历应用程序设计

编写一个应用程序,设计一个窗体,该窗体为BorderLayout布局。窗体的中心添加一个Panel容器:Panel容器的布局是7行7列的GridLayout布局,Panel容器中放置49个标签,用来显示日历。窗口的北面添加一个Panel容器,其布局是FlowLayout布局,Panel容器中放置两个按钮:nextMonth和previousMonth。窗口的南面添加一个Panel容器,其布局是FlowLayout,Panel容器中放置一个标签用来显示一些信息。

Java实验指导书KT20xx版

请按以下步骤完成程序设计:

1) 编写CalendarBean类,实现日期类:

public class CalendarBean {

String day[];

int year = 2013, 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;

}

//返回某年某月1号开始的日期数组 public String[] getCalendar() { String a[] = new String[42];

Calendar 日历 = Calendar.getInstance();

//注意:1月份是从0开始,所以要减1

日历.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;

}

if (month == 2) {

if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {

day = 29;

} else {

day = 28;

}

}

}

2) 补充代码,完成日历窗体界面类设计:

public class CalendarFrame extends Frame {

Label labelDay[] = new Label[42];

Label labelYear;

Button titleName[] = new Button[7];

Button nextMonth, previousMonth;

Label showMessage;

TextField inputYear;

CalendarBean calendar; } for (int i = 星期几, n = 1; i < 星期几 + day; i++) { a[i] = String.valueOf(n); n++; } return a;

String name[] = { "日", "一", "二", "三", "四", "五", "六" }; int year = 2013, month = 1; String days[]; public CalendarFrame() { calendar = new CalendarBean(); calendar.setYear(year); calendar.setMonth(month); days = calendar.getCalendar(); ScrollPane scrollPane = new ScrollPane(); scrollPane.add(getCenterPanel()); add(scrollPane,BorderLayout.CENTER);// 窗口添加scrollPane在中心区域 add(getNorthPanel(),BorderLayout.NORTH); // 窗口添加pNorth 在北面区域

add(getSouthPanel(),BorderLayout.SOUTH); // 窗口添加pSouth 在南区域。

【补充代码】// 窗口添加scrollPane在中心区域

【补充代码】// 窗口添加pNorth 在北面区域 【补充代码】// 窗口添加pSouth 在南区域。 } private Panel getNorthPanel() { Panel panel = new Panel(); 【补充代码…】 labelYear=new Label("请输入年份:"); inputYear=new TextField(5); nextMonth=new Button("上月"); previousMonth=new Button("下月"); panel.add(labelYear); panel.add(inputYear); panel.add(nextMonth);

panel.add(previousMonth);

return panel; } private Panel getCenterPanel() { Panel panel = new Panel();

panel.setLayout(new GridLayout(7, 7 )); // 将panel的布局设置为7行7列的GridLayout布局

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

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

panel.add(titleName[i]) ; // panel添加组件titleName[i]。 } for (int i = 0; i < 42; i++) { labelDay[i] = new Label("", Label.CENTER); panel.add(labelDay[i]) ; // panel添加组件labelDay[i]。 } for (int i = 0; i < 42; i++) { labelDay[i].setText(days[i]); } return panel; } private Panel getSouthPanel() { Panel panel = new Panel(); 【补充代码…】 showMessage=new Label(); showMessage.setText("日历:"+calendar.getYear()+"年"+ calendar.getMonth()+"月" );panel.add(showMessage);

return panel; }

}

3) 设计主应用程序类: public class CalendarMainClass {

public static void main(String args[]) {

CalendarFrame frame = new CalendarFrame();

} } frame.setTitle("日历应用程序"); frame.setBounds(100, 100, 360, 300); frame.setVisible(true); frame.validate();

4) 调试、编译和运行程序,并显示正确界面。

实验总结

请书写你对本次实验有哪些实质性的收获和体会,以及对本次实验有何良好的建议?

实验四 Java事件处理

实验目的

1. 掌握Java语言中的事件处理方法

2. 掌握Java语言中事件源、监视器和处理事件的接口的概念

实验导读

1. Java事件处理简介

学习组件除了了解组件的属性和功能外,学习组件除了了解组件的属性和功能外,一个更重要的方面是学习怎样处理组件上发生的界面事件。 当用户在文本框中输入文本后按Enter键、单击按钮、在一个下拉列表框中选择一个条目等操作时,都发生界面事件。在学习处理事件时,必须很好地掌握事件源、监视器、处理事件的接口这三个概念。

? 事件源:

能够产生事件的对象都可以成为事件源,如文本框、按钮、下拉式列表等。也就是说,事件源必须是一个对象,而且这个对象必须是Java认为能够发生事件的对象。

? 监视器:

需要一个对象对事件源进行监视,以便对发生的事件作出处理。事件源通过调用相应的方法将某个对象作为自己的监视器。例如,对于文本框,这个方法是:

addActionListener(监视器);

对于获取了监视器的文本框,当文本框获得输入焦点之后,如果用户按Enter键,Java运行系统就自动用ActionEvent类创建一个对象,即发生了ActionEvent事件。也就是说,事件源获得监视器后,相应的操作就会导致事件的发生,并通知监视器,监视器就会做出相应的处理。

? 处理事件的接口:

监视器负责处理事件源发生的事件。监视器是一个对象,为了让监视器这个对象能对事件源发生的事件进行处理,创建该监视器对象的类必须声明实现相应的接口,即必须在类体中给出该接口中所有方法的方法体,那么当事件源发生事件时,监视器就自动调用类实现的某个接口中的方法。

2. 文本框上的ActionEvent事件

java.awt.event包中提供了许多事件类和处理各种事件的接口。对于文本框,这个接口的名字是ActionListener,这个接口中只有一个方法:

public void actionPerformed(ActionEvent e)

当在文本框中输入字符并按Enter键时,java.awt.event包中的ActionEvent类自动创建一个事件对象,并将它传递给actionPerformed(ActionEvent e)方法中的参数e,监视器自动调用这个方法对发生的事件做出处理。

所以,称文本框这个事件源可以发生ActionEvent类型事件。为了能监视到这种类型的事件,事件源必须使用addActionListener方法获得监视器;创建监视器的类必须实现接口ActionListener。只要学会了处理

文本框这个组件上的事件,其他事件源上的事件的处理也就很容易学会,所不同的是事件源能发生的事件类型不同,所使用的接口不同而已。

ActionEvent类有如下常用的方法:

? public Object getSource() ActionEvent对象调用该方法可以获取发生ActionEvent事件的事件源对象

的引用,即getSource()方法将事件源上转型为Object对象,并返回这个上转型对象的引用。

? public String getActionCommand() ActionEvent对象调用该方法可以获取发生ActionEvent事件时,

和该事件相关的一个命令字符串,对于文本框,当发生ActionEvent事件时,文本框中的文本字符串就是和该事件相关的一个命令字符串。

3. 选择框和下拉列表上的ItemEvent事件

选择框从未选中状态变成选中状态或从选中状态变成未选中状态时、下拉列表选项列表中选中某个选项时就发生ItemEvent事件,即ItemEvent类自动创建一个事件对象。

发生ItemEvent事件的事件源获得监视器的方法是addItemListener(监视器)。处理ItemEvent事件的接口是ItemListener,创建监视器的类必须实现ItemListener接口,该接口中只有一个方法。当选择框发生ItemEvent事件时,监视器将自动调用接口方法:

itemStateChanged(ItemEvent e)

对发生的事件进行处理。

4. 鼠标事件

任何组件上都可以发生鼠标事件,如:鼠标进入组件、退出组件、在组件上方单击鼠标、拖动鼠标等都触发组件发生鼠标事件,也就是说,组件可以成为发生鼠标事件的事件源。

使用MouseListener接口可以处理5种操作触发的鼠标事件:

(1)在事件源上按下鼠标键。

(2)在事件源上释放鼠标键。

(3)在事件源上击鼠标键。

(4)鼠标进入事件源。

(5)鼠标退出事件源。

鼠标事件的类型是MouseEvent,即当发生鼠标事件时,MouseEvent类自动创建一个事件对象。 MouseListener接口中的方法:

(1)mousePressed(MouseEvent) 负责处理在组件上按下鼠标触发的鼠标事件,当在组件上按下鼠标时,监视器将自动调用接口中的这个方法对事件作出处理。

(2)mouseReleased(MouseEvent) 负责处理在组件上释放鼠标触发的鼠标事件,当在组件上释放鼠标时,监视器将自动调用接口中的这个方法对事件作出处理。

(3)mouseEntered(MouseEvent) 负责处理鼠进入组件触发的鼠标事件,当鼠标进入组件上方时,监视器将自动调用接口中的这个方法对事件作出处理。

(4)mouseExited(MouseEvent) 负责处理鼠标离开组件触发的鼠标事件,当鼠标离开组件时,监视器

自动调用接口中的这个方法对事件作出处理。

(5)mouseClicked(MouseEvent) 负责处理在组件上单击或连击鼠标触发的鼠标事件,当单击或连击鼠标时,监视器自动调用接口中的这个方法对事件作出处理。

MouseMotionListener接口:

使用MouseMotionListener接口可以处理以下两种操作触发的鼠标事件:

(1)在事件源上拖动鼠标。

(2)在事件源上移动鼠标。

MouseMotionListener接口中有如下方法:

(1)mouseDragged(MouseEvent) 负责处理在组件上拖动鼠标触发的鼠标事件,当在组件上拖动鼠标时,监视器调用接口中的这个方法对事件作出处理。

(2)mouseMoved(MouseEvent) 负责处理在组件上运动鼠标触发的鼠标事件,当在组件上运动鼠标时,监视器调用接口中的这个方法对事件作出处理

5. 焦点事件

组件可以触发焦点事件。组件可以使用

public void addFocusListener(FocusListener listener)

增加焦点事件监视器。

当组件获得焦点监视器后,如果组件从无输入焦点变成有输入焦点或从有输入焦点变成无输入焦点都会触发FocusEvent事件。创建监视器的类必须要实现FocusListener 接口,该接口有两个方法:

public void focusGained(FocusEvent e)

public void focusLost(FocusEvent e)

当组件从无输入焦点变成有输入焦点触发FocusEvent事件时,监视器调用类实现的接口方法:focusGained(FocusEvent e);当组件从有输入焦点变成无输入焦点触发FocusEvent事件时,监视器调用类实现的接口方法:focusLost(FocusEvent e)。

用户通过单击组件可以使得该组件有输入焦点,同时也使得其他组件变成无输入焦点。一个组件也可以调用

public boolean requestFocusInWindow()

方法获得输入焦点。

6. 键盘事件

当按下、释放或敲击键盘上一个键时就发生了键盘事件,在Java1.2事件模式中,必须要有发生事件的事件源。当一个组件处于激活状态时,敲击键盘上一个键就导致这个组件上发生了键盘事件。

事件源使用addKeyListener方法获得监视器。

使用KeyListener接口处理键盘事件 .接口KeyListener中有3个方法:

public void keyPressed(KeyEvent e),

public void keyTyped(KeyEvent e),

public void KeyReleased(KeyEvent e)。

当按下键盘上某个键时,监视器就会发现,然后keyPressed方法会自动执行,并且KeyEvent类自动创建一个对象传递给keyPressed方法中的参数e。keyTyped方法是keyPressed和KeyReleased方法的组合,当键被按下又释放时,keyTyped方法被调用。

用KeyEvent类的public int getKeyCode()方法,可以判断哪个键被按下、敲击或释放,getKeyCode方法返回一个键码值。也可以用KeyEvent类的public char getKeyChar()判断哪个键被按下、敲击或释放,getKeyChar方法返回键上的字符。

键盘事件KeyEvent对象调用getModifiers()方法,可以返回整数值ALT_MASK、CTRL_MASK、SHIFT_MASK,它们分别是InputEvent类的类常量。

程序可以通过getModifiers()方法返回的值处理组合键事件。例如,对于KeyEvent对象e,当按下CTRL+X组合键时,下面的逻辑表达式为true:

e. getModifiers() == InputEvent.CTRL_MASK&&e.getKeyCode() == keyEvent.VK_X

Java事件处理就是基于这种授权模式,即发生相应事件的事件源对象,比如sourceObject,通过调用相应的方法:

sourceObject. addXXXListener(监视器);

将某个对象作为自己的监视器。

创建监视器对象的类必须声明实现相应的事件接口:

class A implements XXXListener

当事件源发生事件时,监视器将调用接口中相应的方法做出处理。Java使用了接口回调技术设计了它的处理事件模式,注意到

addXXXListener(XXXListener listener)

方法中的参数是一个接口类型,listener可以引用任何实现了XXXListener接口的类所创建的对象,当事件源发生事件时,接口listener立刻回调类实现的接口中的某个方法。

事件的处理过程如下图所示:

监视器回调接口方法 事件源.addXXXListener(

Java实验指导书KT20xx版

Java实验指导书KT20xx版

图 事件处理示意图

内部类实例做监视器:

Java支持在一个类中声明另一个类,这样的类成为内部类,而包含内部类的类成为内部类的外嵌类,外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。匿名类是内部类的特殊情形,即省略类声明,可以直接用类体创建对象,因此,可以使用匿名内部类的对象做监视器。例如:

xxx.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

}

});

实验内容

1. 图形用户界面设计程序(ArtFont.java)

在实验三第1题的基础上,添加事件处理机制,并逐步完善程序功能。分别用ArtFont类的对象做监视器和匿名内部类的对象做监视器实现。

要求实现如下功能:

? 当在文本框中输入文字后回车,在文本域中显示输入的文字。

? 当分别选择粗体和斜体复选框时,文本域中的文字分别显示粗体和斜体样式。

? 当点击颜色按钮时,出现颜色选择对话框,选择需要的颜色,按确定按钮后,按钮的前景色

和文本域的前景色设置为选定的颜色。

? 当选择字体样式下拉框中的某一字体样式时,文本域中的文字设置为指定的字体样式。

? 当选择字体大小下拉框中的某一字体大小时,文本域中的文字设置为指定的字体大小。

? 当选择窗体样式下拉框中的某一窗体效果时,窗体外观改变为指定的窗体外观。

Java实验指导书KT20xx版

Java实验指导书KT20xx版

代码提示:

1) 用ArtFont类的对象做监视器

public class CopyOfArtFont extends JFrame implements ActionListener, ItemListener {

JComboBox windowStyle;// 窗体样式下拉框 JCheckBox boldBx;// 粗体按钮 JButton colorBtn;// 颜色按钮 JTextField inputText;// 文字输入框 private JPanel getNorthPanel() { JPanel panel = new JPanel(); inputText.addActionListener(this); colorBtn.addActionListener(this); return panel; } private JPanel getCenterPanel() { JPanel panel = new JPanel(); boldBx.addItemListener(this); return panel; } private JPanel getSouthPanel() { JPanel panel = new JPanel(); windowStyle.addItemListener(this); return panel; } @Override public void itemStateChanged(ItemEvent e) { if(e.getSource() == windowStyle){ String s = (String) e.getItem(); String className = "";

if (s.equals("Windows显示效果"))

className =

"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; else if (s.equals("Unix显示效果"))

className =

"com.sun.java.swing.plaf.motif.MotifLookAndFeel"; else if (s.equals("默认显示效果"))

className =

UIManager.getCrossPlatformLookAndFeelClassName(); try {

UIManager.setLookAndFeel(className);

SwingUtilities.updateComponentTreeUI(this); } catch (Exception de) {

System.out.println("Exception happened!"); }

}

}

@Override

public void actionPerformed(ActionEvent e) {

}

}

2) 用匿名内部类的对象做监视器

public class CopyOfArtFont extends JFrame {

JComboBox fontType;// 字体样式下拉框, JCheckBox boldBx;// 粗体按钮 JButton colorBtn;// 颜色按钮; JTextField inputText;// 文字输入框; private JPanel getNorthPanel() { JPanel panel = new JPanel(); inputText.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { } }); return panel; } private JPanel getCenterPanel() { JPanel panel = new JPanel(); boldBx.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { } }); return panel;

} } private JPanel getSouthPanel() { JPanel panel = new JPanel(); fontType.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { } }); return panel; }

2. 日历应用程序设计

在实验三第2题的基础上,添加事件处理机制,并逐步完善程序功能。分别用CalendarFrame类的对象做监视器和匿名内部类的对象做监视器实现。

要求实现如下功能:

? 在文本框inputYear中输入年份,验证年份的有效性;按回车键后,显示输入年份的正确日历 ? 单击previousMonth按钮可以显示当前月的上一月的日历;如果月份小于1,则显示上一年的

12月

? 单击nextMonth按钮,可以显示当前月的下一月的日历;如果月份大于1,则显示下一年的1

3. 英语单词拼写训练程序设计

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

窗口中有一个TextField对象和一个按钮对象,将这两个对象添加到一个面板,然后将该面板添加到窗口的北面。

用户在TextField对象中输入一个英文单词,然后回车或单击按钮,程序将创建若干个标签,其个数刚好等于英文单词所包含的字母的标签,而且每个标签上的名字刚好是英文单词中的一个字母。要求将这些标签按一行添加到一个面板中,然后将该面板添加到窗口的中心。

用户用鼠标单击一个标签后,然后按下键盘上的“→”、“←”键交换相邻标签上的字母,使得这些标签上字母的排列顺序和英文单词中字母的顺序相同。

请按模板要求,将代码补充完整。程序运行效果如下:

1) RandomString.java public class RandomString {

String str = "";

public String getRandomString(String s) {

StringBuffer strBuffer = new StringBuffer(s);

int m = strBuffer.length();

}

} for (int k = 0; k < m; k++) { int index = (int) (Math.random() * strBuffer.length()); char c = strBuffer.charAt(index); str = str + c; strBuffer = strBuffer.deleteCharAt(index); } return str;

2) LetterLabel.java

import java.awt.*;

import java.awt.event.*;

public class LetterLabel extends Button implements FocusListener, MouseListener {

LetterLabel() { } public static LetterLabel[] getLetterLabel(int n) { } public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { } public void mousePressed(MouseEvent e) { } public void setText(String string) { setLabel(string); } public String getText() { } public void mouseReleased(MouseEvent e) { return getLabel(); requestFocus(); setBackground(Color.cyan); setBackground(Color.red); LetterLabel a[] = new LetterLabel[n]; for (int k = 0; k < a.length; k++) { } return a; a[k] = new LetterLabel(); 【补充代码】 // 将当前对象注册为自身的焦点视器 【补充代码】 // 将当前对象注册为自身的标监视器 setBackground(Color.cyan); setFont(new Font("", Font.BOLD, 30));

} } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { }

3) SpellingWordFrame.java

import java.awt.*;

import java.awt.event.*;

import javax.swing.Box;

public class SpellingWordFrame extends Frame implements KeyListener,

ActionListener { TextField inputWord; Button button; LetterLabel label[]; Panel northP, centerP; Box wordBox;

String hintMessage = "用鼠标单击字母,按左右箭头交换字母,将其排列成所输入的单词";

SpellingWordFrame() { setTitle("英语单词拼写训练"); inputWord = new TextField(12); button = new Button("确定"); button.addActionListener(this); inputWord.addActionListener(this); northP = new Panel(); northP.add(new Label("输入一个英文单词:")); northP.add(inputWord); northP.add(button); centerP = new Panel(); wordBox = Box.createHorizontalBox(); centerP.add(wordBox); add(northP, BorderLayout.NORTH); add(centerP, BorderLayout.CENTER); add(messaageLabel, BorderLayout.SOUTH); setBounds(100, 100, 350, 180); setVisible(true); validate(); addWindowListener(new WindowAdapter() { Label messaageLabel = new Label(hintMessage); String word = "";

} public void windowClosing(WindowEvent e) { } System.exit(0); }); public void actionPerformed(ActionEvent e) { } public void keyPressed(KeyEvent e) { LetterLabel sourceLabel = (LetterLabel) e.getSource(); int index = -1; if (【补充代码】) // 判断按下的是否是←键) { for (int k = 0; k < label.length; k++) { } if (index != 0) { } String temp = label[index].getLabel(); label[index].setLabel(label[index - 1].getLabel()); label[index - 1].setLabel(temp); label[index - 1].requestFocus(); if (label[k] == sourceLabel) { } index = k; break; word = inputWord.getText(); int n = word.length(); RandomString rondom = new RandomString(); String randomWord = rondom.getRandomString(word); wordBox.removeAll(); messaageLabel.setText(hintMessage); if (n > 0) { } label = LetterLabel.getLetterLabel(n); for (int k = 0; k < label.length; k++) { } validate(); inputWord.setText(null); label[0].requestFocus(); 【补充代码】 // 将当前窗口注册为label[k]的键盘监视器 label[k].setLabel("" + randomWord.charAt(k)); wordBox.add(label[k]); } else if (【补充代码】) // 判断按下的是否是→键

} } { } validate(); for (int k = 0; k < label.length; k++) { } if (index != label.length - 1) { } String temp = label[index].getLabel(); label[index].setLabel(label[index + 1].getLabel()); label[index + 1].setLabel(temp); label[index + 1].requestFocus(); if (label[k] == sourceLabel) { } index = k; break; public void keyTyped(KeyEvent e) { } public void keyReleased(KeyEvent e) { } String success = ""; for (int k = 0; k < label.length; k++) { } if (success.equals(word)) { } messaageLabel.setText("恭喜你,你成功了"); for (int k = 0; k < label.length; k++) { } inputWord.requestFocus(); String str = label[k].getLabel(); success = success + str; 【补充代码】//移除label[k]的所注册的键盘监视器 【补充代码】//移除label[k]的所注册的焦点监视器 label[k].setBackground(Color.green);

4) WordMainClass.java

public class WordMainClass {

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

5) 调试、编译和运行程序,并显示正确结果。 实验总结

请书写你对本次实验有哪些实质性的收获和体会,以及对本次实验有何良好的建议?

实验五 多线程程序设计

实验目的

1. 掌握Java语言中多线程编程的基本方法

2. 掌握Runnable接口实现多线程的方法

3. 掌握Thread类实现多线程的用法

实验导读

1. 进程和线程的概念

进程是程序一次动态执行的过程,对应从代码加载、执行到执行结束这样一个完整的过程,也是进程自身从产生、发展到消亡的过程。

线程是比进程更小的执行单元,一个进程在执行过程中,可以产生多个线程。每个线程都有自身的产生、执行和消亡的过程。

2. 线程的状态与生命周期

? 新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它已经有了相应的内存空间和其他资源。

? 运行:线程创建之后就具备了运行的条件,一旦轮到它来享用CPU资源时,即JVM将CPU使用权切换给该线程时,此线程的就可以脱离创建它的主线程独立开始自己的生命周期了(即run方法执行的过程)。

? 中断:有4种原因的中断,CPU资源从当前线程切换给其他线程、执行了sleep(int millsecond)方法、执行了wait()方法、进入阻塞状态 。

? 死亡:run方法结束。

3. 线程的创建

在Java语言中,与线程支持密切相关的是java.lang.Thread类和java.lang.Runnable接口。Runnable接口定义很简单,只有一个run方法。任何一个类如果希望自己的实例能够以线程的形式执行,都可以来实现Runnable接口。

继承Thread类和实现Runnable接口,都可以用来创建Thread对象,效果上并没有什么不同。继承Thread类的方法很明显的缺点就是这个类不能再继承其他的类了,而实现Runnable接口不会有这个麻烦。 另外,在继承Thread类的代码中,this其实就是指当前正在运行的线程对象,如果使用实现Runnable接口的方式,要得到当前正在执行的线程,需要使用Thread.currentThread()方法。

线程创建后仅仅是占有了内存资源,在JVM管理的线程中还没有这个线程,此线程必须调用start()方法(从父类继承的方法)通知JVM,这样JVM就会知道又有一个新一个线程排队等候切换了。 注意:多次启动一个线程,或者启动一个已经运行的线程对象是非法的,会抛出IllegalThreadStateException异常对象。

4. 线程的优先级

同一时刻在等待队列中的线程会有很多个,它们各自任务的重要性有所不同。为了加以区分,使工作安排和资源分配时间更为合理,每个线程可以被赋予不同的优先级,让任务比较急的线程拥有更高的优先级,从而更快地进入执行状态。

Java中提供了10个等级的线程优先级,最低为Thread.MIN_PRIORITY=1,最高为

Thread.MAX_PRIORITY=10,默认优先级为Thread.NORM_PRIORITY=5。

使用Thread类中的setPriority(int)方法可以为线程指定优先级。

5. 线程的常用方法

? start() 方法:

线程调用该方法将启动线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。

? run()方法:

Thread类的run()方法与Runnable接口中的run()方法的功能和作用相同,都用来定义线程对象被调度之后所执行的操作,都是系统自动调用而用户程序不得引用的方法。系统的Thread类中,run()方法没有具体内容,所以用户程序需要创建自己的Thread类的子类,并重写run()方法来覆盖原来的run()方法。当run方法执行完毕,线程就变成死亡状态。

? sleep(int millsecond) 方法:

现程占有CPU期间,执行sleep方法来使自己放弃CPU资源,休眠一段时间。休眠时间的长短由sleep方法的参数决定,millsecond是毫秒为单位的休眠时间。如果线程在休眠时被打断,JVM就抛出InterruptedException异常。因此,必须在try~catch语句块中调用sleep方法。

? isAlive() 方法:

线程处于“新建”状态时,线程调用isAlive()方法返回false。当一个线程调用start()方法,并占有CUP资源后,该线程的run方法就开始运行,在线程的run方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true。当线程进入“死亡”状态后(实体内存被释放),线程仍可以调用方法isAlive(),这时返回的值是false。

一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体,由于线程只能引用最后分配的实体,先前的实体就会成为“垃圾”,并且不会被垃圾收集机收集掉。

? currentThread() 方法:

currentThread()方法是Thread类中的类方法,可以用类名调用,该方法返回当前正在使用CPU资源的线程。

? interrupt() 方法:

intertupt方法经常用来“吵醒”休眠的线程。当一些线程调用sleep方法处于休眠状态时,一个占有CPU资源的线程可以让休眠的线程调用interrupt 方法“吵醒”自己。

6. 线程的同步

线程同步是指几个线程都需要调用一个同步方法(使用关键字synchronized修饰的方法) 。

当一个线程A使用一个synchronized修饰的方法时,其他线程想使用这个方法时就必须等待,直到线程

A 使用完该方法 (除非线程A使用wait主动让出CPU资源)。

一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。其它线程如果在使用这个同步方法时如果不需要等待,那么它用完这个同步方法的同时,应当执行notifyAll()方法通知所有的由于使用这个同步方法而处于等待的线程结束等待。

? 挂起:

有时候两个线程并不是同步的,即不涉及都需要调用一个同步方法,但线程也可能需要暂时的挂起。所谓挂起一个线程就是让线程暂时让出CPU的使用权限,暂时停止执行,但停止执行的持续时间不确定,因此不能使用sleep方法暂停线程。挂起一个线程需使用wait方法,即让准备挂起的线程调用 wait 方法,主动让出CPU的使用权限.

? 恢复:

为了恢复该线程,其它线程在占有CUP资源期间,让挂起的线程的目标对象执行notifyAll()方法,使得挂起的线程继续执行;如果线程没有目标对象,为了恢复该线程,其它线程在占有CUP资源期间,

让挂起的线程调用notifyAll()方法,使挂起的线程继续执行。

实验内容

1. 汉字识别程序

编写一个Java应用程序,在主线程中再创建一个Frame类型的窗口,在该窗口中再创建一个线程giveWord。线程giveWord每隔6秒钟给出一个汉字,用户使用一种汉字输入法将该汉字输入到文本框中。请按模板要求,将代码补充完整。

WordThread.java

import java.awt.*;

public class WordThread extends Thread {

char word;

Label com;

WordThread(Label com) {

this.com = com;

}

public void run() {

while (true) {

word = (char) (Math.random()*(29968-19968)+19968);

System.out.println(word);

com.setText("" + word);

try {

}

ThreadFrame.java

public class ThreadFrame extends Frame implements ActionListener { Label wordLabel;

Button button;

TextField inputText, scoreText;

【补充代码】 // 用WordThread声明一个giveWord对象 int score = 0; ThreadFrame() { wordLabel = new Label(" ", Label.CENTER); wordLabel.setFont(new Font("", Font.BOLD, 72)); button = new Button("开始"); inputText = new TextField(3); scoreText = new TextField(5); scoreText.setEditable(false); 【补充代码】 // 调用sleep方法使得线程中断6000豪秒 } catch (InterruptedException e) {} } }

【补充代码】// 创建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 (!(【补充代码】)) // giveWord调用方法isAlive()

{

giveWord = new WordThread(wordLabel);

}

try {

【补充代码】// giveWord调用方法start()

} catch (Exception exe) {

}

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

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

}

scoreText.setText("得分:" + score);

inputText.setText(null);

}

}

}

WordThread.java

public class ThreadWordMainClass {

public static void main(String args[]) {

new ThreadFrame();

}

}

2. 双线程接力

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

60)。

阅读并分析以下程序,将程序中的代码补充完整,编译并运行程序,查看结果。

MoveButton.java

import java.awt.*;

import java.awt.event.*;

public class MoveButton extends Frame implements Runnable,ActionListener { 【补充代码】 //用Thread类声明first,second两个线程对象

Button redButton,greenButton,startButton;

int distance=10;

MoveButton()

{ 【补充代码】 //创建first线程,当前窗口做为该线程的目标对象

【补充代码】 //创建first线程,当前窗口做为该线程的目标对象

redButton=new Button();

greenButton=new Button();

redButton.setBackground(Color.red);

greenButton.setBackground(Color.green);

startButton=new Button("start");

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(【补充代码】) //判断当前占有CPU资源的线程是否是first { moveComponent(redButton);

try{ Thread.sleep(20);

}

catch(Exception exp){}

}

if(【补充代码】) //判断当前占有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[])

{ new MoveButton();

}

}

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

3. 线程的控制

编写一个程序,动画显示文本域中的字符串。

1) 阅读并分析以下程序,将程序中的代码补充完整,编译并运行程序,查看结果。

import java.awt.BorderLayout;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JTextArea;

import javax.swing.border.BevelBorder;

public class RunnableDemo extends JFrame implements Runnable {

// 动画显示的文本字符串 private String introduction = "现在大家已经对计算机很熟悉了,如今计算机的操作" + "系统可以同时执行多个任务,在听歌的同时能够打字、下载文件,在聊天窗口打" + "字的时候,对方同时还能通过视频看到你;听到你。这一切都是使用多任务实现" + "的,Java语言使用多线程实现一个程序中的多个任务同时运行。程序员可以在程" + "序中执行多个线程,每一个线程完成一个功能,并与其他线程并发执行,这种机"

+ "制被称为多线程。";

JTextArea textArea; // 文本域组件

JLabel label;

Thread thread;

public RunnableDemo() {

setTitle("线程的控制");

label = new JLabel("多线程简介:"); // 标签组件

getContentPane().add(label, BorderLayout.NORTH);// 添加标签到窗体 textArea = new JTextArea("\t"); // 初始化文本域组件

textArea.setBorder(new BevelBorder(BevelBorder.LOWERED));// 设置边框 textArea.setLineWrap(true); // 设置自动折行

getContentPane().add(textArea, BorderLayout.CENTER);// 添加文本域组件到文本框

setBounds(100, 100, 383, 225); // 设置窗体大小位置

} setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // 显示窗体 【补充代码】 //创建thread线程,当前窗口做为该线程的目标对象 【补充代码】 //启动thread线程 } //Runnable接口方法,是线程的执行方法 @Override public void run() { String[] intros = introduction.split(""); // 将字符串分割为数组 for (String ch : intros) { // ForEach遍历字符串数组 textArea.append(ch); // 添加一个字符到文本域 try { 【补充代码】 // 线程休眠0.1秒 } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String args[]) { new RunnableDemo(); // 创建本类实例对象 }

2) 在窗体的南面添加三个按钮,为程序添加线程控制功能,要求点击开始按钮(startBtn),线程开

始启动,文字逐个显示,并且将按钮状态改变为禁用(因为线程不能重复启动);点击暂停按钮(pauseBtn),线程暂停,文字显示停止;点击恢复按钮(resumeBtn),线程恢复运行,文字继续显示。当线程执行完毕后,恢复开始按钮的状态为可用。程序运行界面如下图所示:

实验总结

请书写你对本次实验有哪些实质性的收获和体会,以及对本次实验有何良好的建议?

Java实验指导书KT20xx版

实验六 网络编程

【实验目的】

(1) 掌握InetAddress类的使用;

(2) 掌握URL类的使用:URL的概念和编程;

(3) 理解Socket的工作机理,掌握Socket编程的方法;

(4) 学会编写基于网络的Java应用程序,将所学知识进行综合运用。

【实验内容】

1.使用InetAddress类的方法获取http://www./的主机的IP地址;获取本地机的名称和IP地址。

2.使用Socket编程,客户机发送数据到服务器,服务器将接收到的数据返回给客户机。

3.将上面的程序进行改写,使用多线程实现服务器能同时处理多个客户机的请求。

(一)练习使用InetAddress类。对程序进行分析,写出分析结果。

import java.net.*;

public class GetIP {

public static void main(String args[]) {

try {

} InetAddress address_1 = InetAddress.getLocalHost(); // 获得本地主机的计算机名和IP地址 System.out.println(address_1.toString()); InetAddress address_2 = InetAddress.getByName("res."); // 获得主机地址的域名和IP地址 System.out.println(address_2.toString()); InetAddress address_3 = InetAddress.getByName("61.183.20.30"); System.out.println(address_3.toString()); } } catch (UnknownHostException e) { System.out.println("无法找到…………."); }

(二) 阅读下面的程序并补充完整,掌握获取URL信息的一些方法。

import java.net.*;

import java.io.*;

public class URLTest {

public static void main(String[] args) { URL url = null; InputStream is; try { url = new URL("http://res.:8080/eas/index.html");

} is = url.openStream(); int c; try { while ((c = is.read()) != -1) System.out.print((char) c); } catch (IOException e) { } finally { } e.printStackTrace(); e.printStackTrace(); is.close(); } catch (MalformedURLException e) { } catch (IOException e) { System.out.println("文件名:" + 【代码1】); //获取url对象的文件名

System.out.println("主机名:" + 【代码2】); //获取主机名 System.out.println("端口号:" + 【代码3】); //获取端口号

} System.out.println("协议名:" + 【代码4】); //获取协议名称 }

(三)练习使用Socket和ServerSocket进行套接字编程

下面是一个简单的字符界面的聊天程序。实验该程序,两人一组在局域网上实现简单的聊天。然后编写图形用户界面的程序实现聊天功能。

服务器端程序如下:

import java.io.*;

import java.net.*;

public class ServerDemo {

public static void main(String args[]){ try{ ServerSocket server=new ServerSocket(4566); Socket socket=server.accept(); String line;

BufferedReader is=new BufferedReader(

new InputStreamReader(socket.getInputStream()));

PrintWriter os=new PrintWriter(socket.getOutputStream()); BufferedReader sin=new BufferedReader( System.out.println("Client:"+is.readLine()); System.out.print("Server:"); line=sin.readLine(); while(!line.equals("bye")){ new InputStreamReader(System.in));

}

} } } os.println(line); os.flush(); System.out.println("Client:"+is.readLine()); System.out.print("Server:"); line=sin.readLine(); sin.close(); os.close(); is.close(); socket.close(); server.close(); System.out.println("Error:"+e); }catch(Exception e){

客户端程序如下:

import java.io.*; import java.net.*;

public class ClientDemo {

public static void main(String args[]){ try{ Socket socket=new Socket("127.0.0.1",4566); BufferedReader is=new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter os=new PrintWriter(socket.getOutputStream()); BufferedReader sin=new BufferedReader( new InputStreamReader(System.in)); String readline; System.out.print("Client:"); readline=sin.readLine(); while(!readline.equals("bye")){ } sin.close(); os.close(); is.close(); socket.close(); os.println(readline); os.flush(); System.out.println("Server:"+is.readLine()); System.out.println("Client:"); readline=sin.readLine();

} } }catch(Exception e){ } System.out.println("Error:"+e);

思考:如何实现服务器同时和多个客户机的通信。

实验七 多媒体技术

【实验目的】

熟悉图形、图像的使用方法,理解计算机动画的原理和 Java 的多线程处理机制,能够编写在 Applet和Application中加载和显示图像,掌握声音和动画的播放方法。

【实验性质】

设计性实验(学时数:4H)

【实验要求】

1.了解图片的装载、显示和修改显示的大小;

2.了解Image类和ImageIcon类的常用的方法;

3.了解动画的原理;

4. 了解Java Sound API,了解和利用Applet和AudioClip实现声音的播放控制;

【实验内容】

练习1:利用java.applet.AudioClip实现简易声音播放器

利用java.applet.AudioClip实现简易声音播放器,可以播放一个当前目录下的声音文件如spacemusic.au,可以通过按钮控制声音的播放、循环播放和停止播放三种功能。阅读分析SoundTest程序,将程序中的代码补充完整。编译程序,并查看结果。

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class SoundTest extends JApplet implements ActionListener{

JButton playButton;

JButton loopButton;

JButton stopButton;

JLabel statusLabel;

JPanel buttonPanel;

Container container;

String bgMusicName=" Wav/receivemedia.au ";

AudioClip bgMusicClipOnce,bgMusicClipLoop;

boolean loopStatus;

public void init() {

container=getContentPane();

container.setLayout(new BorderLayout());

playButton=new JButton("播放");//定义播放按钮

loopButton=new JButton("循环");//定义循环播放按钮

stopButton=new JButton("停止");//定义停止播放按钮

playButton.addActionListener(this);

loopButton.addActionListener(this);

stopButton.addActionListener(this);

buttonPanel=new JPanel();

buttonPanel.add(playButton);

buttonPanel.add(loopButton);

buttonPanel.add(stopButton);//将按钮放置到buttonPanel中;

container.add(buttonPanel,BorderLayout.NORTH);

statusLabel=new JLabel("状态:装载声音");//设置状态标签

container.add(statusLabel,BorderLayout.SOUTH);

//放置状态面板到窗口最下方

loadMusic();//装载音乐;

setSize(500,500);

setVisible(true);

}

public void loadMusic(){

try{

bgMusicClipOnce=Applet.newAudioClip(getClass().getResource("Wav/receivemedia.au"));//装载一次播放的背景音乐receivemedia.au

bgMusicClipLoop=Applet.newAudioClip(getClass().getResource("Wav/receivemedia.au"));//装载可循环播放的背景音乐receivemedia.au

}catch(Exception e){

System.err.println("不能打开声音文件!!!");

}

}

public void startMusic(){//开始播放声音

if(loopStatus)//如果循环播放状态;

bgMusicClipLoop. 代码1 ;//循环播放声音bgMusicClipLoop

else

bgMusicClipOnce. 代码2 ;//播放一次声音bgMusicClipOnce

}

public void loopMusic(){//循环播放声音

if(!loopStatus){//如果当前状态是非循环状态

loopStatus=true;//改变为循环状态为真;

bgMusicClipOnce. 代码3 ;//一次播放声音片段bgMusicClipOnce停止;

bgMusicClipLoop. 代码4 ;//循环播放声音片段bgMusicClipLoop播放; }

bgMusicClipLoop. 代码5 ;//声音片段bgMusicClipLoop循环播放; }

public void stopMusic(){//停止播放声音;

if(loopStatus){

bgMusicClipLoop.stop();

}

bgMusicClipOnce.stop();

}

public void actionPerformed(ActionEvent e){

if(e.getSource()==playButton){

startMusic();

playButton.setEnabled(false);

loopButton.setEnabled(true);

stopButton.setEnabled(true);

statusLabel.setText("状态:播放....");

}

else if(e.getSource()==loopButton){

loopMusic();

loopButton.setEnabled(false);

playButton.setEnabled(true);

stopButton.setEnabled(true);

statusLabel.setText("状态:循环播放中....");

}

else if(e.getSource()==stopButton){

stopMusic();

stopButton.setEnabled(false);

playButton.setEnabled(true);

loopButton.setEnabled(true);

statusLabel.setText("状态:停止....");

}

}

public void start(){

SoundTest st=new SoundTest();

}

}

练习2:使用滚动条改变背景颜色

程序功能:移动滚动条可以改变背景颜色。

阅读并分析以下程序,将程序中的代码补充完整。编译程序,并查看结果。

import java.applet.Applet;

import java.awt.*;

import java.awt.event.*;

import java.awt.Scrollbar;

import java.awt.Color;

public class KY7_2 extends Applet implements AdjustmentListener {

Scrollbar r1, r2, r3; int red, green, blue; TextField t; Label a; public void init() { setLayout(null); r1 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); r2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); r3 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); t = new TextField("0", 5); t.setEditable(false); a = new Label("移动滚动条可改变背景颜色", Label.CENTER); add(a); a.setBounds(120, 10, 150, 15); 代码1 ; //添加滚动条r1 r1.setBounds(20, 30, 100, 20); 代码2 ; //添加滚动条r2 r2.setBounds(140, 30, 100, 20); 代码3 ; //添加滚动条r3 r3.setBounds(260, 30, 100, 20); add(t); t.setBounds(20, 120, 220, 18); r1.addAdjustmentListener(this); 代码4 ; 代码5 ; } public void adjustmentValueChanged(AdjustmentEvent e) { red = r1.getValue(); 代码6 ; 代码7 ; t.setText("red 的值" + String.valueOf(r1.getValue()) + ",green 的值" + String.valueOf(r2.getValue()) + ",blue 的值"

+ String.valueOf(r3.getValue()));

} Color c = new Color(red, green, blue); 代码8 ; //设置背景色 }

练习3:创建电闪雷鸣的动画

程序功能:本程序可以通过按钮控制声音和动画的开始和停止操作。动画显示了电闪雷鸣的场面。注意:图像文件要分别表现不同时间段的电闪场面,这样才会有动画效果。

阅读并分析以下程序,将程序中的代码补充完整。编译程序,编写浏览 Applet 的页面文件,在浏览器运行结果。

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class KY7_3 extends Applet implements Runnable, ActionListener {

public void start() { } public void stop() { if (aThread != null) { if (aThread == null) { } aThread = new Thread(this); 代码2 // 线程启动 b1.setEnabled(false); Image iImages[]; // 图像数组 Thread aThread; int iFrame; // 图像数组下标 AudioClip au; // 定义一个声音对象 Button b1, b2; public void init() { } int i, j; iFrame = 0; aThread = null; iImages = new Image[10]; for (i = 0; i < 10; i++) { } au = getAudioClip(getDocumentBase(), "Wav/receivemedia.au"); 代码1 // 播放一次声音文件 Panel p1 = new Panel(); b1 = new Button("开始"); b2 = new Button("停止"); p1.add(b1); p1.add(b2); b1.addActionListener(this); b2.addActionListener(this); setLayout(new BorderLayout()); add(p1, "South"); iImages[i] = getImage(getCodeBase(), "images/" + "tu" + (i + 1)+ ".JPG");

} } } 代码3 // 线程中断 aThread = null; 代码4 // 停止播放声音文件 public void run() { } public void update(Graphics g) { } public void actionPerformed(ActionEvent e) { } if ((e.getSource() == b1) && (aThread == null)) { // 单击 Start 按钮时触发 aThread = new Thread(this); 代码5 // 线程启动 b1.setEnabled(false); b2.setEnabled(true); g.drawImage(iImages[iFrame], 0, 0, this); while (true) { } iFrame++; iFrame %= (iImages.length); // 下一幅图像的下标 repaint(); try { Thread.sleep(100); } catch (InterruptedException e) { // 中断时抛出 break; // 退出循环 } 代码6 // 循环播放声音文件 } if ( 代码7 ) { // 单击 Stop 按钮时触发 aThread.interrupt(); // 线程中断 aThread = null; b1.setEnabled(true); b2.setEnabled(false); au.stop(); // 停止播放声音文件 }

练习4:编写一个播放音乐的应用程序,当客户选择某个音乐之后,程序在适当位置显示一幅图像。

练习5:编写一个实现如下功能的Applet:从它的HTML中取3个参数x、y、op做算术运算,其中x、y为int型数据,op为运算符(+、-、*、/之一),请显示x op y的结果。思考:

怎样在Java应用程序中实现上述过程。

参考文献:

1. 《Java2实用教程(第三版)》耿祥义、张跃平编著,清华大学出版社。

2.《Java2实用教程(第三版)实验指导与习题解答》耿祥义、张跃平编著,清华大学出版社。

3.《Java开发实战宝典》,李钟尉等编著,清华大学出版社。

附录一 Java Code之多态

通过一个简单的例子理解多态的概念

/**

* 人民警察

*/

public interface IPolice {

/**

* 抓小偷

*/

public void catchThief();

}

/**

* 一个警察,执行抓小偷任务.

*/

public class PoliceReal implements IPolice { public void catchThief() {

System.out.println("抓住小偷了");

}

}

/**

* 另一个警察,也执行抓小偷任务.

*/

public class PoliceHyp implements IPolice { public void catchThief() {

System.out.println("大冷天的抓什么小偷啊,不如偷个菜."); }

}

/**

* 市民

*/

public class Citizen {

private String mName;

public Citizen(String name) {

mName = name;

}

/**

* 市民报案

*/

public void report(IPolice police) {

System.out.println(String.format("市民%s丢失手机,向警察报案抓小偷.", mName));

police.catchThief();

}

}

案情:

市民虽然向警察报了案,

但你不知道能不能把小偷抓住,

甚至你都不知道他们有没有去抓小偷,

还有可能你在电影里看到的剧情真的发生了...

事情经过可能是这样:

public class Main {

public static void main(String[] args) {

Citizen citizen = new Citizen("张三");

IPolice police = getPolice();

citizen.report(police);

}

private static IPolice getPolice() {

return new PoliceReal();

}

}

事情结果一:

市民张三丢失手机,向警察报案抓小偷.

抓住小偷了

事情经过也可能是这样:

public class Main {

public static void main(String[] args) {

Citizen citizen = new Citizen("张三");

IPolice police = getPolice();

citizen.report(police);

}

private static IPolice getPolice() {

return new PoliceHyp();

}

}

事情结果二:

市民张三丢失手机,向警察报案抓小偷.

大冷天的抓什么小偷啊,不如偷个菜.

事情经过还可能是这样:

public class Main {

public static void main(String[] args) {

Citizen citizen = new Citizen("张三");

IPolice police = getPolice();

citizen.report(police);

}

private static IPolice getPolice() {

return new PoliceReal() {

@Override

public void catchThief() {

System.out.println("抓小偷?笑话,抓了小偷我哪儿收保护费去啊.");

}

};

}

}

事情结果三:

市民张三丢失手机,向警察报案抓小偷.

抓小偷?笑话,抓了小偷我哪儿收保护费去啊.

附录二 内部类的用法

public class China {

final String nationAnthem = "义勇军进行曲";

//内部类声明的对象,作为外嵌类的成员

Beijing beijing;

China() {

beijing = new Beijing();

}

String getSong(){

return nationAnthem;

}

//内部类的声明

class Beijing{

String name="北京";

void speak(){

System.out.println("我们是:" + name + " 我们的国歌是:" + getSong()); }

}

public static void main(String[] args) {

China china = new China();

china.beijing.speak();

}

}

附录三 和类有关的匿名类

class Cubic{

double getCubic(int n){

return 0;

}

}

abstract class Sqrt{

public abstract double getSqrt(int x);

}

class A{

void f(Cubic cubic){

//执行匿名类体中重写的getCubic

double result = cubic.getCubic(3);

System.out.println(result);

}

}

public class anonymousClass {

public static void main(String[] args) {

A a = new A();

//使用匿名类创建对象,将该对象传递给方法f的参数cubic a.f(new Cubic(){

@Override

double getCubic(int n) {

return n*n*n;

}

});

//使用匿名类创建对象,ss是该对象的上转型对象

//匿名类是abstract类Sqrt的一个子类,所以必须要实现getSqrt方法 Sqrt ss = new Sqrt() {

@Override

public double getSqrt(int x) {

return Math.sqrt(x);

}

};

//上转型对象调用子类重写的方法

double m = ss.getSqrt(5);

System.out.println(m);

}

}

附录四 和接口有关的匿名类

interface Cubic{

double getCubic(int n);

}

interface Sqrt{

public double getSqrt(int x);

}

class A{

void f(Cubic cubic){

//执行匿名类体中实现的getCubic

double result = cubic.getCubic(3); System.out.println(result);

}

}

public class anonymousClass {

public static void main(String[] args) {

A a = new A();

//使用匿名类创建对象,将该对象传递给方法f的参数cubic a.f(new Cubic(){

public double getCubic(int n) { return n*n*n;

}

});

//使用匿名类创建对象,接口ss存放该对象的引用

//匿名类是实现Sqrt接口的类,所以必须要实现getSqrt方法 Sqrt ss = new Sqrt() { public double getSqrt(int x) { return Math.sqrt(x);

}

};

//接口回调类实现的方法

double m = ss.getSqrt(5);

System.out.println(m);

}

}

更多相关推荐:
C语言实验指导及报告模板

语言程序江西理工大学设计1C附件1实验报告模板C语言程序设计实验报告实验一简单的C程序教学班级冶金136学号01姓名张博课程教师胡春安实验教师胡春安完成时间20xx20xx学年第1学期江西理工大学2实验一简单的...

行政案例方法与实例实验指导书

前言行政案例分析课程的首要特点是强调理论联系实际的学习方法要求学生运用已学的行政学基本理论对当前行政管理领域的重特大事件公共政策规范等进行分析剖析该事件或该公共政策的问题成因探讨解决该问题的可能途径丰富对该类社...

VC++实验指导书

VC程序设计实验指导书张位勇湖南工学院前言VisualC实验环境介绍一VisualC简介VisualC是Microsoft公司的VisualStudio开发工具箱中的一个C程序开发包VisualStudio提供...

Web技术实验指导书

Web技术实验指导书内容简介Web技术是计算机专业学生的一门专业课程着重讲述Web编程的技术方法对于学生从事Web系统的研发使用和维护有重要意义本课程概念多内容涉及面广系统性强通过本课程的学习学生应能从软件硬件...

C_sharp实验指导书

实验指导实验一VS20xx集成开发环境一实验目的熟悉VS20xx开发环境掌握如何在此环境下开发简单的NET应用程序以及调试程序的基本操作技巧二实验要求123熟悉VSNET环境按照C规范正确写源程序能得到正确的程...

设计性实验论文范例与书指导

设计性实验论文范例与书指导,内容附图。

设计性实验论文范例与书指导

设计性实验论文范例与书指导,内容附图。

数据结构实验指导书

数据结构实验教学大纲课程编号020xx3040课程学时学分603实验总学时10课程英文名称DataStructure课程类别技术基础课开出学期第四学期第六学期开出单位实验室信息学院教学机房制定人张丽霞讲师一制定...

数据库原理本科实验指导综合

数据库原理实验指导书数据库原理实验指导书实验一建立数据库一实验目的1了解SQLServer20xx2掌握SQLServer20xx数据库的建立和删除二实验内容1查看SQLServer20xx的所有组件2使用服务...

序号8-0914070030-12-20xx-20xx-01程序设计语言Ⅱ实验指导书

辽东学院自编教材程序设计语言实验指导书齐文编计算机科学与技术专业用辽东学院20xx年12月I目录C概论和输入输出1类和对象6派生类与继承12多态性16IO流与异常处理19面向对象程序设计方法与实例23I实验一实...

实验指导书《大型数据库(Oracle)》

大型数据库Oracle实验指导实验一Oracle安装与维护一实验目的1了解并掌握Oracle10的安装方法2了解并掌握测试安装好的Oracle10g的方法二实验内容及步骤1软件下载Oracle公司针对个人学习之...

数据结构实验指导书(广工)

数据结构作业和实验指导书数据结构课程组广东工业大学计算机学院20xx年3月目录第1章概述11课程教材和实验12作业和实验安排第2章算法设计实验和上机21数据结构习题概述22算法设计的上机作业要求23算法设计上机...

实验指导语(22篇)