全部_JAVA教程

上传人:cn****1 文档编号:568240343 上传时间:2024-07-23 格式:PPT 页数:918 大小:6.11MB
返回 下载 相关 举报
全部_JAVA教程_第1页
第1页 / 共918页
全部_JAVA教程_第2页
第2页 / 共918页
全部_JAVA教程_第3页
第3页 / 共918页
全部_JAVA教程_第4页
第4页 / 共918页
全部_JAVA教程_第5页
第5页 / 共918页
点击查看更多>>
资源描述

《全部_JAVA教程》由会员分享,可在线阅读,更多相关《全部_JAVA教程(918页珍藏版)》请在金锄头文库上搜索。

1、Java实用教程 Java 实用教程用教程 JavaJavaJavaJavaJava实用教程 Java环境及配置环境及配置 Java基本语法基本语法 NUIX常用命令常用命令 类和接口类和接口 集合集合第第4章章 Java Applet 第第5章章 Java图形处理图形处理 第第6章章 Java用户界面技术用户界面技术 异常、事件和多线程机制异常、事件和多线程机制 Java数据库技术数据库技术 PLSQL Java读写读写XML技术技术 javascript技术技术 JSP技术技术 Servlet技术技术 Hibernate技术技术 Struts2技术技术 Spring技术技术 Java实用教

2、程NUIX命令: konsole exit find / -name/user/group name/size n eg: find /demo -HelloWorld.java pwd ls -al cd cat file1 file2 mkdir m/p cp -r t* eg: cp r /d* . rm rf filename1 filename2 filename3 filename4 filename5 mv -i/-f grep Eg: grep upp telnet ftp su chmod man文本文件编辑器:Vi .bash_profileJava实用教程基础知识 数据类

3、型数据类型常量和变量常量和变量标识符,关键字标识符,关键字 (1) 标识符由字母、数字、下划线(_)、美元符号($)组成,但美元符号用得较少。 (2) 标识符可以以字母、下划线或美元符号开始。 (3) Java语言中,标识符大小写敏感,必须区别对待。 (4) 标识符没有最大长度的限制,但最好表达特定的意思。 (5) 标识符定义不能是关键字。运算符和表达式运算符和表达式 算术运算符、赋值运算符、关系运算符、布尔逻辑运算符、位运算符。流程控制流程控制数组数组Java实用教程2.2 数据类型、变量和常量数据类型、变量和常量2.2.1 数据类型数据类型 Java编程语言定义了八种基本的数据类型(见表2

4、.2),共分为四类:整数类(byte、short、int、long)、文本类(char)、浮点类(double、float)和逻辑类(boolean)。Java实用教程表表2.2 Java的数据类型的数据类型Java实用教程1. 整数类整数类(1) 采用三种进制十进制、八进制和十六进制。2 十进制值是2;077 首位的0表示这是一个八进制的数值;0xBAAC 首位的0x表示这是一个十六进制的数值。(2) 具有缺省int。(3) 用字母“L”和“l”定义long。(4) 所有Java编程语言中的整数类型都是带符号的数字。Java实用教程 2. 文本类文本类 (1) 代表一个16 bit Unic

5、ode字符。 (2) 必须包含用单引号( )引用的文字。 (3) 使用下列符号: a一个字符。 t-一个制表符。 u? -一个特殊的Unicode字符,?应严格使用四个十六进制数进行替换。Java实用教程 3. 浮点类浮点类 默认为double类型,如果一个数字包括小数点或指数部分,或者在数字后带有字母F或f(float)、D或d(double),则该数字为浮点数。Java实用教程4. 逻辑类逻辑类boolean数据类型有两种值:true和false。例如:boolean flag = true;上述语句声明变量flag为boolean 类型,它被赋予的值为true。Java实用教程2.2.2

6、 变量与常量变量与常量 常量是指整个运行过程中不再发生变化的量,例如数学中的= 3.1415,在程序中需要设置成常量。而变量是指程序的运行过程中发生变化的量,通常用来存储中间结果,或者输出临时值。 变量的声明也指变量的创建。执行变量声明语句时,系统根据变量的数据类型在内存中开辟相应的存储空间并赋予初始值。变量有一个作用范围,超出它声明语句所在的块就无效。Java实用教程 下面看一个使用各种类型变量声明并改变的示例。程序中pi为常量,s1、i1、l1、ch1、f1、d1、b1为全局变量,可以在方法change中发生改变,然后在方法main中输出。而s2、i2、l2、ch2、f2、d2、b2是方法

7、main的局部变量,它们的作用范围只局限于方法main中。 【例2.2】测试不同数据类型的变量,程序输出如图2.2所示。源程序代码如下:/程序文件名称为SetVariable.javapublic class SetVariable/全局变量Java实用教程static double pi = 3.141592654;/数学常量static short s1;static int i1;static long l1;static char ch1;static float f1;static double d1;static boolean b1;public static void main

8、(String args)Java实用教程/局部变量short s2 = 35;int i2 = -32;long l2 = 34555L;char ch2 = A;float f2 = 897.89F;double d2 = 34.345;boolean b2 = false;/输出常量System.out.println(数学常量pi = + pi); /输出局部变量Java实用教程System.out.println(*局部变量*);System.out.println(短整型变量s2 = + s2);System.out.println(整型变量i2 = + i2);System.ou

9、t.println(长整型变量l2 = + l2);System.out.println(字符变量ch2 = + ch2);System.out.println(浮点数类型f2 = + f2);System.out.println(双精度型变量d2 = + d2);System.out.println(布尔型变量b2 = + b2); /调用方法修改全局变量的值Java实用教程change();/输出全局变量的值System.out.println(*全局变量*);System.out.println(短整型变量s1 = + s1);System.out.println(整型变量i1 = +

10、i1);System.out.println(长整型变量l1 = + l1);System.out.println(字符变量ch1 = + ch1);System.out.println(浮点数类型f1 = + f1);System.out.println(双精度型变量d1 = + d1);System.out.println(布尔型变量b1 = + b1);Java实用教程 /方法:修改全局变量的值 public static void change() s1 = 125;i1 = 88;l1 = 987654321L;ch1 = B;f1 = 3.2590F;d1 = -1.04E-5;b

11、1 = true; Java实用教程2.3 运算符和表达式运算符和表达式 Java常用的运算符分为五类:算术运算符、赋值运算符、关系运算符、布尔逻辑运算符、位运算符。位运算符除了简单的按位操作外,还有移位操作。按位操作返回布尔值。 表达式是由常量、变量、对象、方法调用和操作符组成的式子。表达式必须符合一定的规范,才可被系统理解、编译和运行。表达式的值就是对表达式自身运算后得到的结果。 根据运算符的不同,表达式相应地分为以下几类:算术表达式、关系表达式、逻辑表达式、赋值表达式,这些都属于数值表达式。Java实用教程2.3.1 算术运算符及算术表达式算术运算符及算术表达式Java中常用的算术运算符

12、如下:+加运算符-减运算符*乘运算符/除运算符%取模运算(除运算的余数)+增量运算符 -减量运算符 Java实用教程 【例例2.3】测试运算符及表达式,程序输出如图2.3所示。源程序代码如下:/程序文件名称为NumberOper.javapublic class NumberOperpublic static void main(String args)/变量初始化int a = 30;int b = 20;/定义结果变量int r1,r2,r3,r4,r5,r6,r7,r8,r9;/计算结果r1 = a + b;Java实用教程r2 = a-b;r3 = a * b;r4 = a / b;r

13、5 = a % b;r6 = a +;r7 = b-;r8 = + a;r9 = - b;/输出结果System.out.println(a = + a + b = + b); /a,b的值System.out.println(a+b = + r1);System.out.println(a-b = + r2);Java实用教程System.out.println(a*b = + r3);System.out.println(a/b = + r4);System.out.println(a%b = + r5);System.out.println(a+ = + r6);System.out.p

14、rintln(b- = + r7);System.out.println(+a = + r8);System.out.println(-b = + r9); Java实用教程2.3.2 关系运算符关系运算符 关系运算符用于比较两个数据之间的大小关系,关系运算表达式返回布尔值,即“真”或“假”。Java中的常用关系运算符如下:= =等于! =不等于大于=大于等于=小于等于Java实用教程 【例2.4】编写程序,测试关系运算符及其表达式,程序输出如图2.4所示。源程序代码如下:/程序文件名称为TestRelation.javapublic class TestRelationpublic stat

15、ic void main(String args)/变量初始化int a = 30;int b = 20;/定义结果变量boolean r1,r2,r3,r4,r5,r6;/计算结果Java实用教程2.3.3 布尔逻辑运算符布尔逻辑运算符表表2.3 布尔运算符及规则布尔运算符及规则Java实用教程 图2.3为布尔逻辑运算符及其规则示例等。其中简洁与和简洁或的执行结果分别与非简洁与和非简洁或的执行结果是一致的,不同在于简洁与检测出符号左端的值为假时,不再判断符号右端的值,直接将运算结果置为假;而简洁或与非简洁或的不同在于简洁或检测出符号左端为真时,不再判断符号右端的值,直接将运算结果置为真。例如

16、:Boolean a = false;Boolean b = true; a & b检测到a为假,则无需判断b的值,直接将值置为假;而b | a时检测到b为真,则无需判断a的值,直接将值置为真。Java实用教程 【例2.5】测试布尔表达式,程序输出结果如图2.5所示。源程序代码如下:/程序文件名称为TestLogic.javapublic class TestLogicpublic static void main(String args)/变量初始化boolean a = false;boolean b = true;/定义结果变量boolean r1,r2,r3,r4,r5,r6;/计算结

17、果Java实用教程r1 = !a;r2 = a & b;r3 = a | b;r4 = a b;r5 = a & b;r6 = a | b;/输出结果System.out.println(a = + a + b = + b);System.out.println(!a = + r1); System.out.println(a&b = + r2);System.out.println(a|b = + r3);System.out.println(ab = + r4);System.out.println(a&b = + r5);System.out.println(a|b = + r6);Ja

18、va实用教程2.3.4 位运算符位运算符Java中的常用位运算符如下:位求反&按位与|按位或按位异或右移不带符号右移 右移运算符对应的表达式为xa,运算的结果是操作数x被2的a次方来除,左移运算符对应的表达式为xa,运算的结果是操作数x乘以2的a次方。Java实用教程2.3.4 位运算符位运算符Java中的常用位运算符如下:位求反&按位与|按位或按位异或右移不带符号右移 右移运算符对应的表达式为xa,运算的结果是操作数x被2的a次方来除,左移运算符对应的表达式为xa,运算的结果是操作数x乘以2的a次方。Java实用教程 【例2.6】测试位运算符,程序输出结果如图2.6所示。源程序代码如下:/程

19、序文件名称为TestBit.javapublic class TestBitpublic static void main(String args)/变量初始化int a = 36;int b = 2;/定义结果变量int r1,r2;Java实用教程/计算结果r1 = a b;r2 = a b = + r1); System.out.println(a3)?5:3;则a的值为5。如果x = 2,则a的值为3。Java实用教程 对象运算符(instanceof)用来判断一个对象是否属于某个指定的类或其子类的实例,如果是,返回真(true),否则返回假(false)。 例如: boolean b

20、 = userObject instanceof Applet用来判断userObject类是否是Applet类的实例。Java实用教程2.3.7 优先级优先级表表2.5 运算符优先级运算符优先级Java实用教程2.4 流流 程程 控控 制制 流程控制分为三种基本结构:顺序结构、分支结构和循环结构。顺序结构是指命令行顺序执行,这是最常见的一个格式;分支结构是一种选择结构,根据条件的值选择不同的执行流程,可以得到不同的结果。分支结构包括单分支语句(if-else语句)和多分支语句(switch语句);循环结构是指对于一些重复执行的语句,用户指定条件或次数,由机器自动识别执行。循环结构包括次数循环

21、语句(for语句)和条件循环语句(while语句)。Java实用教程2.4.1 分支语句分支语句分支语句分为两类:单分支语句和多选语句。1. if-else语句语句if-else语句的基本格式为:if(布尔表达式)语句或块1;else语句或块2;Java实用教程 其中: (1) 布尔表达式返回值为true或false。 (2) 如果为true,则执行语句或块1,执行完毕跳出if-else语句。 (3) 如果为false,则跳过语句或块1,然后执行else下的语句或块2。Java实用教程 【例2.7】测试if-else语句,如果x10,则输出x的值,并提示结果正确,否则输出x= 10,提示结果不

22、正确。程序输出结果如图2.7所示。源程序代码如下:/程序文件名称为TestIf.javapublic class TestIf/声明全局变量xstatic int x;public static void main(String args)x = 12;if(x10)Java实用教程 System.out.println(x = + x + 结果正确);else System.out.println(x = 10 + 结果不正确);change();System.out.println(修改x的值之后);if(x10)System.out.println(x = + x + 结果正确);els

23、eSystem.out.println(x = 10 + 结果不正确);Java实用教程/change方法:修改x的值public static void change()x = 5; Java实用教程2. switch语句switch语句的基本格式为:switch(表达式1)case 表达式2: 语句或块2; break;case表达式3: 语句或块3; break;case 表达式4: 语句或块4; break;default: 语句或块5; break;Java实用教程其中:(1) 表达式1的值必须与整型兼容。(2) case分支要执行的程序语句。(3) 表达式2、3、4是可能出现的值。

24、(4) 不同的case分支对应着不同的语句或块序列。 (5) break表示跳出这一分支。 Java实用教程 【例2.8】测试switch语句,当x=1、2、3时,分别打印1、2、3,x不为这三个值时,打印x的值。程序输出结果如图2.8所示。源程序代码如下:/程序文件名称为TestSwitch.javapublic class TestSwitchpublic static void main(String args)/声明变量xint x;x = 12; Java实用教程System.out.println(x=12时打印的值);choose(x);x = 3;System.out.prin

25、tln(x=3时打印的值);choose(x);/choose方法:switch语句结构public static void choose(int x)switch(x) Java实用教程case 1:System.out.println(1);break;case 2:System.out.println(2);break;case 3:System.out.println(3);break;default:System.out.println(x); Java实用教程2.4.2 for循环语句循环语句for循环语句实现已知次数的循环,其基本格式为:for(初始化表达式;测试表达式;步长)语

26、句或块;Java实用教程 其执行顺序如下: (1) 首先运行初始化表达式。 (2) 然后计算测试表达式,如果表达式为true,执行语句或块;如果表达式为false,退出for循环。 (3) 最后执行步长。 Java实用教程 【例2.9】用for循环统计1100(包括100)之间数的总和。程序输出结果如图2.9所示。源程序代码如下:/程序文件名称为TestFor.javapublic class TestForpublic static void main(String args) int sum = 0; for(int i = 1; i=100; i+)sum += i; System.ou

27、t.println(1到100(包括100)的数的总和为: + sum);Java实用教程2.4.3 while循环语句循环语句 while循环语句实现受条件控制的循环,其基本格式为: while(布尔表达式) 语句或块; 当布尔表达式为true时,执行语句或块,否则跳出while循环。Java实用教程上面for循环语句的例子改为while语句后如下所示:int sum = 0;int i = 1;while (i=100)sum += i; i+;System.out.println(1到100(包括100)的数的总和为: + sum);Java实用教程2.4.4 do语句语句do语句实现受

28、条件控制的循环,其基本格式为:do语句或块;while(布尔表达式)Java实用教程 先执行语句或块,然后再判断布尔表达式。与while语句不同,当布尔表达式一次都不为true时,while语句一开始判断就跳出循环,不执行语句或块,而在do语句中则要执行一次。上面那个例子改为do循环为: int sum = 0; int i = 1; do sum += i; i+; while (i=100); System.out.println(1到100(包括100)的数的总和为: + sum);Java实用教程2.5 数数 组组 的的 使使 用用2.5.1 数组声明数组声明 数组的定义如下: (1)

29、 首先是一个对象。 (2) 存放相同的数据类型,可以是原始数据类型或类类型。 (3) 所有的数组下标默认从0开始,而且访问时不可超出定义的上限,否则会产生越界错误。Java实用教程 数组声明时实际是创建一个引用,通过代表引用的这个名字来引用数组。数组声明格式如下: 数据类型 标识符 例如: int a;/声明一个数据类型为整型的数组a pencil b;/声明一个数据类型为pencil类的数组bJava实用教程2.5.2 创建数组创建数组 由于数组是一个对象,所以可以使用关键字new来创建一个数组,例如:a = new int10;/创建存储10个整型数据的数组ab = new pencil2

30、0;/创建存储20个pencil类数据的数组b 数组创建时,每个元素都按它所存放数据类型的缺省值被初始化,如上面数组a的值被初始化为0,也可以进行显式初始化。在Java编程语言中,为了保证系统的安全,所有的变量在使用之前必须是初始化的,如果未初始化,编译时会提示出错。有两种初始化数组的方式,分别如下:Java实用教程(1) 创建数组后,对每个元素进行赋值。a0=5;a1=4;.a9 = 10;(2) 直接在声明的时候就说明其值,例如:Int a = 4,5,1,3,4,20,2;说明了一个长度为7的一维数组。Java实用教程 【例2.10】编写程序测试数组,程序输出结果如图2.10所示。源程序

31、代码如下:/程序文件名称为TestArray.javapublic class TestArraypublic static void main(String args)/声明数组int a;char b;/创建数组Java实用教程a = new int3;b = new char2;/数组初始化for (int i = 0; i3; i+)ai = i*3;b0 = a;b1 = b;/快速初始化数组int c = 0,1*3,2*3;/输出结果System.out.print(数组an);Java实用教程for (int i = 0; i2; i+)System.out.print(bi

32、+ );System.out.print(n数组cn);for (int i = 0; i3; i+)System.out.print(ci + ); Java实用教程 编写程序,用数组实现乘法小九九的存储和输出。【提示:采用多个一维数组。】Java实用教程表表2.1 转转 义义 符符Java实用教程Integer.toString(age, 10);Integer.toBinaryString(20013);Integer.toHexString(i);(int i=达) Math.sqrt(2); 常用转义字符: n /newLine 换行 r /return 回车 t /tab f /换

33、页 / “ / ” / u4e2d / unicode 转义 u0030 / 0 u0000 /将以下是进制转化为二进制,八进制,十六进制:134 126 178 四舍五入运算:double price = 34.56;long pay = (long)(price+0.5);输出AZ之间的随机字符:int x = random.nextInt(26);ch = (char)(x+A);从控制台接收一个整数 Scanner console = new Scanner(System.in); int n=console.nextInt();条件表达式:double userRate = year

34、s60;isMan | age+ 60;! isMan & age+60;! isMan & age+60;Java实用教程实现交换:int j = r.nextInt(i); String card = cardsi; cardsi = cardsj; cardsj = card; i-; 数组的访问: 1 使用ary.length 属性可以获取数组的长度 2 数组的下标(index)从0开始, 最大是length-1,一共length个元素. 3 可以使用下标访问指定的元素: int a = ary2;/读取 ary2 = 8;/写入 4 如果越界访问会出现异常(错误) ArrayInde

35、xOutOfBoundsExceptionJava实用教程数组的扩展问题 1 Java数组的大小是固定的 2 利用数组复制到方法可以变通的实现数组扩展 3 System.arraycopy() 可以复制数组 4 Arrays.copyOf() 可以简便的创建数组副本 5 创建数组副本的同时将数组长度增加就变通的实现了数组的扩展Arrays.toString(ary1);ary1.lengthsum+=c-0;str.charAt(i);Arrays.copyOf(ary, ary.length+1);Continue;break;System.currentTimeMillis();Array

36、s.sort(ary1);/排序函数barcode.charAt(12)-0;console.nextLine();str.length();DecimalFormat.format(1.41421);Java实用教程第3章类和接口 3.1 类类 3.2 接口接口 3.3 常用数据结构及类常用数据结构及类 习习 题题 Java实用教程JDK包的下载与安装包的下载与安装Java 环环 境境 配配 置置模块拆分模块拆分要求加上包结构,即要求加上包结构,即命名空间,即包的命名规范命名空间,即包的命名规范:Javac命令:命令:javac xxx.java d .-d选项:把编译好的文件放在指定目录下

37、;如果源文件中声明了包结构,系统会自动创建目录;选项:把编译好的文件放在指定目录下;如果源文件中声明了包结构,系统会自动创建目录;Java命令:命令:java 完整包名完整包名.文件名文件名 Java程序的构成程序的构成(参考下一页参考下一页),注释语句,注释语句面向对象和类,构造方法面向对象和类,构造方法,final,static,abstract参数传递和封装,继承,参数传递和封装,继承,Super和和this,引用类型转换,多态,抽象类,接口引用类型转换,多态,抽象类,接口,toString(),hashCode()=和和equal,chatAt();length();trim();in

38、dexOf();lastIndexOf();subString();正则表达式;正则表达式;集合:架构图,集合:架构图,list,set,treeset(二叉树二叉树);如何实现比较,两种方法:如何实现比较,两种方法:Map,hashMap,加载因子加载因子程序运行时的特殊情况:异常和错误程序运行时的特殊情况:异常和错误常见异常,异常分类,异常处理常见异常,异常分类,异常处理(两种方式:捕获与抛出两种方式:捕获与抛出),自定义异常,自定义异常-学会看异常调代码学会看异常调代码 异常原理异常原理.txtTrycatch()finally用法用法 throws,throw,自定义异常,自定义异常

39、自定义异常自定义异常.txt反射:反射:declared修饰符:支持私有,不支持继承修饰符:支持私有,不支持继承取属性:带取属性:带declared取方法:不带取方法:不带declared取构造:不带取构造:不带declared标注和泛型标注和泛型Java实用教程泛型的好处:泛型的好处:1 1避免了类型转换避免了类型转换2 2规范了参数类型规范了参数类型3 3集合中使用多,方便集合中使用多,方便IOIO流:流:FileFile类:类: Mkdir(),createTempFile(),deleteMkdir(),createTempFile(),delete(),(), 取子目录,子文件:取子

40、目录,子文件:list()list(),listFileslistFiles()() Exit(),lengthExit(),length();();分类:按功能:输入输出流;按底层数据操作方式:字节字符流;按操作对象分类:节分类:按功能:输入输出流;按底层数据操作方式:字节字符流;按操作对象分类:节点流包装流(节点流为包装流的参数)点流包装流(节点流为包装流的参数)IOIO流的编程步骤:流的编程步骤:1.1.选节点流选节点流 2.2.选包装流选包装流 3.3.用包装流读写用包装流读写 4.4.关闭包装流关闭包装流字节输入流:字节输入流:fileinputStream,objectinputS

41、tream,datainputStreamfileinputStream,objectinputStream,datainputStream( (支持基本类型,支持基本类型,String)String)字节输出流:字节输出流:fileoutputStream,objectoutputStream,dataoutputStreamfileoutputStream,objectoutputStream,dataoutputStream字符输入流:字符输入流:Reader,bufferedReaderReader,bufferedReader( (字符流字符流) )字符输出流:字符输出流:Write

42、rWriter字节流字节流-字符流字符流inputStreamReaderinputStreamReader-outputstreamWriteroutputstreamWriter配置文件:属性文件配置文件:属性文件.txt/.properties.txt/.properties,用,用propertiesproperties类操作类操作.txt/.properties.txt/.properties文件文件对象序列化对象序列化Java实用教程对象需要在流中使用,需要序列化对象需要在流中使用,需要序列化serializableserializable, , 序列化本类,本类属性,本类属性的属

43、性序列化本类,本类属性,本类属性的属性序列化针对的是具体对象,而非类型;故序列化针对的是具体对象,而非类型;故staticstatic,transienttransient修饰的属性不参与序列化修饰的属性不参与序列化格式化输格式化输 入:入:ScannerScannerIOIO的超级父类:的超级父类:InputStreamInputStream OutStreamOutStream Reader Writer Reader Writer字节流(以字节流(以streamstream为后缀)为后缀) inputStreaminputStream fileInputStreamfileInputSt

44、ream DataInputStreamDataInputStream ObjectInputStreamObjectInputStream outputStreamoutputStream fileOutputStreamfileOutputStream DataOutputStreamDataOutputStream ObjectOutputStreamObjectOutputStream字符流(以字符流(以readerreader为后缀)为后缀) Reader Reader FileReaderFileReader InputStreamReaderInputStreamReader缓冲

45、流缓冲流 Writer Writer FileWriterFileWriter OutputStreamWriterOutputStreamWriter缓冲流:缓冲流: BufferInputStreamBufferInputStream BufferOutputStreamBufferOutputStream BufferedReaderBufferedReader printWriterprintWriter封装流:封装流: Java实用教程线程:什么时候使用线程?线程:什么时候使用线程?OS-OS-进程进程-线程线程JVMJVM是一个进程,多进程之间内存独立,多线程之间对内存共享,栈内存

46、独立;是一个进程,多进程之间内存独立,多线程之间对内存共享,栈内存独立;CPUCPU在同一时间在同一时间点上只能运行一个线程,人的感觉是时间段;点上只能运行一个线程,人的感觉是时间段;100100毫秒毫秒- -100100个个CPUCPU时间片分给不同的线程时间片分给不同的线程线程属于操作系统内某一个进程,线程之间同时运行,不依赖于其他线程,但可能相互影响;线程属于操作系统内某一个进程,线程之间同时运行,不依赖于其他线程,但可能相互影响;JAVAJAVA线程:如何实现一个线程?线程:如何实现一个线程? CPUCPU时间片时间片+ +代码代码+ +数据数据 Thread Thread Runna

47、bleRunnable 继承继承ThreadThread实现实现RunnableRunnable, ,但是但是ThreadThread已经实现了已经实现了RunnableRunnable接口,接口,故只需要继承故只需要继承ThreadThread或者实现或者实现RunnableRunnable接口接口currentThreadcurrentThread()()用于实现了用于实现了RunnableRunnable接口的线程得到姓名等,如果继承了接口的线程得到姓名等,如果继承了ThreadThread类,则用类,则用 thisthis就可以达到目的了。就可以达到目的了。Run()Run()方法不启

48、动新线程,方法不启动新线程,start()start()方法启动新的线程,同一线程只能启动一次;方法启动新的线程,同一线程只能启动一次; 守护线程的存在要依赖于其它的非守护线程;守护线程的存在要依赖于其它的非守护线程;gcgc是守护线程是守护线程在在a a中调中调b.joinb.join()(),a a停止运行,停止运行,b b运行完了运行完了a a再运行;再运行;YeildYeild()()让位:只向优先级高的或平级让位,该线程还继续抢位;让位:只向优先级高的或平级让位,该线程还继续抢位;SynchronizedSynchronized同步关键字:是线程实现串行,两种用法:同步关键字:是线程

49、实现串行,两种用法: 同步方法:同步方法:Synchronized void method()Synchronized void method() 同步语句块:在需要同步的语句中用同步语句块:在需要同步的语句中用synchronized(synchronized(对象对象)所有对象在内存中都有对象锁,同步依靠对象锁完成;所有对象在内存中都有对象锁,同步依靠对象锁完成;同步效率低,应该避免使用;同步效率低,应该避免使用;Java实用教程释放对象锁:释放对象锁:1.1.在同步语句块中未扑获异常在同步语句块中未扑获异常2.2.3.3.4.4.死锁:因为没有释放对象锁而产生死锁;死锁:因为没有释放对象

50、锁而产生死锁;避免死锁原则:避免死锁原则:1.1.顺序上锁顺序上锁 2.2.不要回调不要回调 3.3.反向解锁反向解锁同步原则:同步原则: 1.1.并行语句出问题,必须同步并行语句出问题,必须同步 2.Synchronized2.Synchronized(对象)利用对象锁可以实现同步(对象)利用对象锁可以实现同步 3.3.同步时避免死锁同步时避免死锁StringBuffer,CollectionsStringBuffer,Collections线程状态图:线程状态图:运行运行run()run()结束;有未捕获异常抛出结束;有未捕获异常抛出-消亡消亡运行运行-sleep-sleep();();j

51、oinjoin();等待用户输入();等待用户输入-阻塞阻塞 阻塞阻塞-sleep()-sleep()时间到;时间到;joinjoin线程结束,用户提交线程结束,用户提交- -就绪就绪运行运行执行同步语句块(无对象锁)执行同步语句块(无对象锁)-对象锁池;对象锁池对象锁池;对象锁池-取得对象锁取得对象锁-就绪就绪Wait()Wait():释放对象锁,进等待池:释放对象锁,进等待池 出等待池:出等待池:-1.-1.调调notify(),notifyAll();2.wait()notify(),notifyAll();2.wait()时间到,时间到,-进入对象锁池进入对象锁池生产者消费者模式生产者

52、消费者模式读写锁:所有只读共享锁,所有写线程独占锁;读写锁:所有只读共享锁,所有写线程独占锁;互斥锁:相互排斥互斥锁:相互排斥Java实用教程网络编程网络编程:包括包括IO/Thread/net OSI七层模型:物理层,数据链路层,网络层,传输层,会话层,表现层,应用层七层模型:物理层,数据链路层,网络层,传输层,会话层,表现层,应用层 TCP/IP模型:(物理层,数据链路层,)(网络层)(传输层)(会话层,表现层,应用层)模型:(物理层,数据链路层,)(网络层)(传输层)(会话层,表现层,应用层) 应用层协议:应用层协议:HTTP,FTP,POP3/SMPT,TELNET 传输层协议:传输层

53、协议:TCP,UDP 网络层协议:网络层协议:IP,ICMP 物理链路层:物理链路层:ARP/RARP,OTHERIP:用于网络中计算机的定位,由:用于网络中计算机的定位,由4/6个个0255的数字组成,中间用的数字组成,中间用.隔开;(网卡隔开;(网卡+端口)端口) 计算机交互建立在计算机交互建立在IP和端口基础上和端口基础上 第一个数字第一个数字A类:类:0126,127保留保留IP B类:类:128191 C类:类:192223 D类:类:224端口(端口(socket)范围)范围:065535 固有端口:固有端口:01023 http:80 ftp:21 可用端口:可用端口:10244

54、8xxx(部分可用端口被某些软件占用了)(部分可用端口被某些软件占用了) qq:4000,oracle:1521 ,server8080 , weblogic:7001 动态端口:动态端口:48xxx65535套接字:套接字:IP+端口端口Java实用教程 Server端端 Clientss=new ServerSocket(port); so=new Socket(ip,port);Socket so=ss.accept(); so.getxx得到输入输出流得到输入输出流 so.getxx得到输入输出流得到输入输出流 包装后交互包装后交互包装后交互包装后交互 关闭流,关闭流,socket/s

55、ervletSocket 关闭流,关闭流,socket 单向交流和双向交流的程序单向交流和双向交流的程序: URL类类,InetAddress类类, TCP:保持连接;重发错误数据:保持连接;重发错误数据UDP:不保持连接,不重复发送错误数据(广播协议):不保持连接,不重复发送错误数据(广播协议) 内部类:内部类: 静态内部类静态内部类 成员内部类成员内部类 局部内部类局部内部类 匿名内部类匿名内部类 Static内部类看成一个内部类看成一个static属性属性/方法方法 成员内部类:成员内部类: 局部内部类:就像局部变量一样;局部内部类:就像局部变量一样; 可以使用成员变量和可以使用成员变量

56、和final修饰的局部内部类修饰的局部内部类 匿名内部类:无类名,无匿名内部类:无类名,无Class关键字,有继承关系,无继承关键字,无构造关键字,有继承关系,无继承关键字,无构造 Swing : 布局管理布局管理 Java实用教程Java实用教程 2. 类的定义类的定义 Java源程序中可以有多个类的定义,但必须有一个主类,这个主类是Java程序运行的入口点。在应用程序中,主类为包含main方法的类;在Applet中,主类为用户自定义的系统Applet类的扩展类。在Java源程序中,主类的名字同文件名一致。 类的定义又包括类头声明和类体定义。类体中包括属性声明和方法描述。下面来看一个例子,其

57、中斜体表示的语句行为主类类头,主类类头下面从大括号“”开始到“”结束的部分称为主类类体。Java实用教程2.1.2 物理构成物理构成 Java源程序物理上由三部分构成,分别为语句、块和空白。 (1) 语句指一行以分号“;”结束的语句。 (2) 块指用括号对界定的语句序列,块可以嵌套使用。 (3) 空白指语句之间、块内部或者块之间的空白行。空白不影响Java源程序的编译和运行,适当地运用空白,可以形成良好的代码风格。Java实用教程例例 子子 程程 序序 【例1.1】源程序名称为HelloWorld.java,命令行提示符下输出字符串“Hello World”。源代码如下:/程序文件名称为Hel

58、loWorld.javaPackage day01;public class HelloWorldpublic static void main(String args)System.out.println(Hello World);Java实用教程2.1 Java程序的构成程序的构成2.1.1 逻辑构成逻辑构成 Java源程序逻辑构成分为两大部分:程序头包的引用和类的定义。 1. 程序头包的引用程序头包的引用 主要是指引用JDK软件包自带的包,也可以是自己定义的类。引用之后程序体中就可以自由应用包中的类的方法和属性等。Java实用教程在例1.1中,Label lblName;TextFiel

59、d txtName;TextField txtDisp;都是语句,而lblName = new Label(请输入您的名字:);txtName = new TextField(8);txtDisp = new TextField(20);add(lblName);add(txtName);add(txtDisp);txtName.addActionListener(this);是块,语句之间、块之间或块内部的空行都为空白。Java实用教程2.1.3 注释语句注释语句 注释语句主要用来进行一些说明,或者标记一些无用的程序语句。有两种注释方法,行注释为以/开始的行;块注释以/*开始和*/结束,Ja

60、va编译器忽略注释后的程序语句或说明。例如,下面的语句就是注释语句用来说明程序文件名称的。/程序文件名称为WelcomeApplet.java上述的语句注释可以更改为:/*程序文件名称为WelcomeApplet.java*/或/*程序文件名称为WelcomeApplet.java*/Java实用教程3.1 类类3.1.1 类的定义和声明类的定义和声明 Java编程语言是面向对象的,处理的最小的完整单元为对象。而现实生活中具有共同特性的对象的抽象就称之为类。类由类声明和类体构成,类体又由变量和方法构成。下面给出一个例子来看一下类的构成。 【例3.1】自定义一个apple类,在主类SetAppl

61、e中创建实例并调用方法,输出结果如图3.1所示。源程序代码如下:Java实用教程/程序文件名为SetApple.javapublic class SetApplepublic static void main(String args)apple a = new apple();/创建apple类a.appleweight = 0.5;/实例变量赋值System.out.println(苹果的重量为1两);System.out.println(a.bite();/调用实例方法a.appleweight = 5;System.out.println(苹果的重量为5两);System.out.pri

62、ntln(a.bite();Java实用教程class apple /属性long applecolor;/对应苹果的颜色double appleweight;/苹果的重量boolean eatup;/是否吃完public boolean bite() /类方法if (appleweight5000)str = 名字: + name + Salary: + salary;elsestr = 名字: + name + Salary: 低于5000;Java实用教程return str;class Employee public String name;/名字public int salary;/

63、薪水public static String getSalary(String name, int salary) String str;str = 名字: + name + Salary: + salary;return str;Java实用教程public static String getSalary2(String name, int salary) String str;str = 名字: + name + Salary: + salary; return str; ;Java实用教程 程序中定义了父类Employee类,它有两个方法getSalary和getSalary2,方法体的

64、实现都是一致的,都为输出名字和薪水的值。在TextExtend主类中覆盖了getSalary方法,方法体重新定义为薪水低于5000时并不输出薪水的值而是输出“低于5000”,用于和继承的getSalary2方法进行比较。由图3.2可以看出覆盖的方法按主程序中重定义的方法调用,而继承的方法直接调用父类中的方法。Java实用教程3.1.3 特殊变量特殊变量 类中有两个特殊变量super和this。 1. super 类声明中用关键字extends扩展了其超类之后,super用在扩展类中引用其超类中的成员变量。 【例3.3】使用super变量,输出结果如图3.3所示。源程序代码如下:/程序文件名为U

65、seSuper.javapublic class UseSuperJava实用教程public static void main(String args)Manager m = new Manager();m.name = 王飞;m.salary = 10000;m.department = 业务部;System.out.println(m.getSalary();class Employee Java实用教程public String name;/名字 public int salary;/薪水/方法 public String getSalary() String str;str = 名字

66、: + name + nSalary: + salary; return str; class Manager extends Employee Java实用教程 public String department;/部门 /方法 public String getSalary() /使用super变量调用超类的方法 return super.getSalary() + nDepartment: + department; Java实用教程 2. this this变量指向当前对象或实例。 str = 名字: + name + nSalary: + salary; 上例中的语句可以换成下面的语句

67、。 str = 名字: + this.name + nSalary: + this.salary; 这两者是等同的,因为在Java编程语言中,系统自动将this关键字与当前对象的变量相关联。但有一种情况例外,就是当在某些完全分离的类中调用一个方法并将当前对象的一个引用作为参数传递时。例如: Day d = new Day(this); Java实用教程3.1.4 构造函数构造函数 类中的构造函数用来初始化一个类。构造函数为公有类型,无返回值,用来从类实例中访问类时初始化此类的私有变量。 【例3.4】基于例3.3将公有变量改成私有变量之后,增加两个构造函数,访问通过外部调用构造函数实现初始化赋值

68、,得到如图3.3所示的结果。/程序文件名为UseConstruct.javapublic class UseConstructpublic static void main(String args)Java实用教程Manager m = new Manager(王飞,10000,业务部);/初始化赋值System.out.println(m.getSalary(); class Employee private String name;/名字 private int salary;/薪水 /构造函数 public Employee(String _name, int _salary) Java

69、实用教程name = _name;salary = _salary; public String getSalary() String str;str = 名字: + name + nSalary: + salary; return str; class Manager extends Employee private String department;Java实用教程/构造函数public Manager(String _name, int _salary, String _department)super(_name,_salary);department = _department;p

70、ublic String getSalary() return super.getSalary() + nDepartment: + department;Java实用教程3.1.5 包包 计算机操作系统使用文件夹或者目录来存放相关或者同类的文档,在Java编程语言中,提供了一个包的概念来组织相关的类。包在物理上就是一个文件夹,逻辑上代表一个分类概念。 包就是指一组类。例如一个名叫Company的包,可以包含一组类,如Employee(雇员)、Manager(管理者)和Department(部门)等。声明包的基本格式如下:Package 包名;Java实用教程 其中:Package为关键字,包

71、名为标识符。 使用包时的注意事项如下: (1) Package语句要作为程序非注释语句的第一行语句。 (2) 包内的类名惟一。 (3) 引用包中的类时,使用import语句。import语句的基本格式为import 包名.类名,其中import为关键字,包名和类名之间用圆点(.)隔开。Java实用教程 【例3.5】编写程序测试包,先建立一个Company文件夹,然后建立名为Manager.java的类文件。源程序代码如下:/程序文件名为Manager.javapackage Company;/声明包名Companyclass Employee public String name;/名字 pu

72、blic int salary;/薪水 public String getSalary() Java实用教程String str;str = 名字: + name + nSalary: + salary; return str; public class Manager extends Employee public String department;/部门public String getSalary() return super.getSalary() + nDepartment: + department;Java实用教程对此文件进行编译,生成类文件Manager.class。在原目录

73、建立源程序文件UsePackage.java。源程序代码如下:/程序文件名UsePackage.javaimport Company.Manager;/引入包中的类public class UsePackagepublic static void main(String args)Manager m = new Manager();m.name = 王飞;m.salary = 10000;m.department = 业务部;System.out.println(m.getSalary();Java实用教程 编译后,在命令提示符状态下运行,输出结果如图3.4所示。从图3.4中可以看出首先进入C

74、ompany目录,编译Manager.java文件,然后返回上层目录,编译UsePackage.java文件,最后执行UsePackage类文件,输出正确的结果。Java实用教程3.2 接接 口口 Java编程语言中禁止多继承属性,但可以通过接口来帮助类扩展方法。接口中可以定义大量的常量和方法,但其中的方法只是一种声明,没有具体的实现,使用接口的类自己实现这些方法。接口与类的不同在于: (1) 没有变量的声明,但可以定义常量。 (2) 只有方法的声明,没有方法的实现。 接口声明的基本格式如下: public interface 接口名 extends 接口列表Java实用教程 【例3.6】测试

75、接口,定义接口文件Product.java,定义了两个常量,声明了一个方法。接口文件如下:/程序文件名Product.javapublic interface Productstatic final String MAKER = 计算机制造厂;static final String ADDRESS = 上海;public int getPrice();Java实用教程使用接口的源文件代码如下:/程序文件名UseInterface.javapublic class UseInterface public static void main(String args) Computer p = new

76、 Computer(); System.out.print(p.ADDRESS + p.MAKER); System.out.println( 计算机的价格: + p.getPrice()+ 万元); Java实用教程class Computer implements Productpublic int getPrice()return 1;Java实用教程3.3 常用数据结构及类常用数据结构及类3.3.1 Vector类类 Vector类似于一个数组,但与数组相比在使用上有以下两个优点。 (1) 使用的时候无需声明上限,随着元素的增加,Vector的长度会自动增加。 (2) Vector提供

77、额外的方法来增加、删除元素,比数组操作高效。Vector类有三个构造函数,分别如下:public Vector();该方法创建一个空的Vector。Java实用教程 public Vector(int initialCapacity); 该方法创建一个初始长度为initialCapacity的Vector。 public Vector(int initialCapacity, int capacityIncrement); 该方法创建一个初始长度为initialCapacity的Vector,当向量需要增长时,增加capacityIncrement个元素。Java实用教程(1) Vector类

78、中添加、删除对象的方法如下:public void add(int index, Object element)在index位置添加对象element。public boolean add(Object o)在Vector的末尾添加对象o。public Object remove(int index)删除index位置的对象,后面的对象依次前提。Java实用教程(2) Vector类中访问、修改对象的方法如下:public Object get(int index)返回index位置对象。public Object set(int index, Object element)修改index位置

79、的对象为element。Java实用教程(3) 其它方法:public String toString()将元素转换成字符串。public int size()返回对象的长度。Java实用教程 【例3.7】操作Vector对象,进行元素的添加、插入、修改和删除。程序输出结果如图3.6所示。源程序代码如下:/程序文件名为UseVector.javaimport java.util.Vector;/引入JDK的Vector类public class UseVectorpublic static void main(String args)Java实用教程Vector vScore = new Ve

80、ctor();vScore.add( 86);/添加元素vScore.add( 98);/添加元素vScore.add(1, 99);/插入元素/输出结果for (int I = 0; I vScore.size(); I+) System.out.print(vScore.get(i) + );vScore.set(1, 77);/修改第二个元素vScore.remove(0); /删除第一个元素Java实用教程System.out.println(n修改并删除之后);for (int I = 0; I vScore.size(); I+)System.out.print(vScore.ge

81、t(i) + );System.out.println( n转换成字符串之后的输出n + vScore.toString(); ;Java实用教程图3.6 操作Vector对象的输出结果Java实用教程3.3.2 Hashtable类类 Hashtable类存储的是对象的名-值对。将对象的名和它的值相关联同时存储,并可以根据对象名来提取它的值。在Hashtable中,一个键名只能对应着一个键值,然而一个键值可以对应多个键名,键名必须是惟一的。构造函数以及常用方法如下:public Hashtable()构建散列表。public Hashtable(int initialCapacity)构建长

82、度为initialCapacity的散列表。public int size()Java实用教程返回散列表的名的个数。public Object remove(Object key)删除散列表中key名及其对应的value值。public Object put(Object key,Object value)将对象名key和对象值value存放到散列表中。public Object get(Object key)返回散列表key名对应的值。public String toString()转换成字符串。Java实用教程 【例3.8】操作Hashtable对象,进行添加、修改、删除等操作,输出结果如

83、图3.7所示。源程序代码如下:/程序文件名为UseHashtable.javaimport java.util.Hashtable;public class UseHashtablepublic static void main(String args) Hashtable hScore = new Hashtable(); hScore.put(张一,86);Java实用教程hScore.put(李二,98);hScore.put(海飞,99);System.out.println(转换成字符串之后的输出: + hScore.toString();hScore.put(李二,77);hSco

84、re.remove(张一);System.out.println(修改并删除之后);System.out.println(转换成字符串之后的输出: + hScore.toString(); Java实用教程3.3.3 Enumeration接口接口 实现Enumeration接口的对象生成一系列元素,通过nextElement()方法依次读取下一个元素。只有以下两个方法: public boolean hasMoreElements() 测试是否还有元素。 public Object nextElement() 返回枚举的下一个元素。 Enumeration接口及其方法通常与Vector、Ha

85、shtable一起连用,用来枚举Vector中的项和Hashtable中的键名,例如: for (Enumeration e = v.elements() ; e.hasMoreElements() ;) System.out.println(e.nextElement();Java实用教程 【例3.9】使用Enumeration接口枚举Vector中的对象和Hashtable对象中的键名,并进行输出,结果如图3.8所示。源程序代码如下:/程序文件名UseEnumeration.javaimport java.util.*;public class UseEnumeration public

86、static void main(String args) Vector vScore = new Vector();vScore.add(86);vScore.add(98);Java实用教程 vScore.add(1,99);System.out.println(Vector: + vScore.toString(); for (Enumeration e = vScore.elements() ; e.hasMoreElements() ;)System.out.println(e.nextElement();Hashtable hScore = new Hashtable();hSco

87、re.put(张一,86);hScore.put(李二,98);hScore.put(海飞,99);System.out.println(Hashtable: + hScore.toString();Java实用教程for (Enumeration e = hScore.keys() ; e.hasMoreElements() ;)String str = (String)e.nextElement();System.out.print(str + :);System.out.println(hScore.get(str); Java实用教程3.3.4 Date类类Date类用来指定日期和时间

88、,其构造函数及常用方法如下:public Date()从当前时间构造日期时间对象。public String toString()转换成字符串。public long getTime()返回自新世纪以来的毫秒数,可以用于时间计算。Java实用教程 【例3.10】测试执行循环花费的时间(数量级为毫秒),具体时间情况如图3.9所示。源程序代码如下:/程序文件名为UseDate.javaimport java.util.Date;public class UseDatepublic static void main(String args) Date dOld = new Date(); long

89、lOld = dOld.getTime(); System.out.println(循环前系统时间为: +dOld.toString();Java实用教程int sum = 0;for (int i=0; i100; i+)sum += i;Date dNew = new Date();long lNew = dNew.getTime();System.out.println(循环后系统时间为: +dNew.toString();System.out.println(循环花费的毫秒数为: + (lNew - lOld); Java实用教程3.3.5 String类类 String类用于操作非数

90、值型字符串,它提供了七类方法操作,分别为字符串创建、字符串长度、字符串比较、字符串检索、字符串截取、字符串运算和数据类型转换。1. 字符串创建字符串创建public String()构造一个空字符串。public String(char value)使用字符数组value中的字符以构造一个字符串。public String(String original)使用原字符串original的拷贝以构造一个新字符串。Java实用教程2. 字符串长度字符串长度public int length()返回字符串的长度。3. 字符串比较字符串比较public boolean equals(Object anO

91、bject)比较字符串是否与anObject代表的字符串相同(区分大小写)。public boolean equalsIgnoreCase(String anotherString)比较字符串是否与anotherString相同(不区分大小写)。Java实用教程4. 字符串检索字符串检索public int indexOf(String str)返回一个字符串中str第一次出现所在的位置。public int indexOf(String str, int fromIndex)返回从fromIndex开始字符串str出现所在的位置。Java实用教程5. 字符串截取字符串截取public Str

92、ing substring(int beginIndex, int endIndex)返回benginIndex到endIndex之间的字符串。6. 字符串运算字符串运算运算符为“+”,表示连接运算。下面的行语句输出连接的字符串。System.out.println(Hashtable: + hScore.toString();Java实用教程 【例3.11】操作字符串,输出结果如图3.10所示。源程序代码如下:/程序文件名为TestString.javapublic class TestStringpublic static void main(String args)String str

93、= new String(The substring begins at the specified beginIndex.);String str1 = new String(string);String str2 = new String();int size = str.length();/字符串长度Java实用教程int flag = str.indexOf(substring);str2 = str.substring(flag,flag + 9);/取子字符串System.out.println(字符串 + str + n总长度为: + size);if(str1.equals(s

94、tr2)/判断是否相等System.out.println(截取的字符串为: + str1);elseSystem.out.println(截取的字符串为: + str2); Java实用教程 7. 数据类型转换数据类型转换 各种原始数据类型与String类型之间可以通过方法相互转换。 valueOf()系列的静态方法用于从其它对象(原始数据类型对象)转换成字符串。例如:public static String valueOf(Boolean b)public static String valueOf(char c)public static String valueOf(int i)pub

95、lic static String valueOf(long l)public static String valueOf(float f)public static String valueOf(double d)Java实用教程具体实例如下:(1) 从int转换到String。例如:int intvar = 1; String strvar; strvar = String.valueOf (intvar); /1Java实用教程(2) 从float转换到String。例如:float fltvar = 9.99f; String strvar; strvar = String.value

96、Of(fltvar); /9.99Java实用教程(3) 从double转换到String。例如:double dblvar = 99999999.99; String strvar; strvar = String.valueOf (dblvar); /9.999999999E7Java实用教程(4) 从char转换到String。例如:char chrvar = a; String strvar; strvar = String.valueOf (chrvar); /aJava实用教程(5) 从String转换到int、float、long、double。例如:String intstr

97、= 10; String fltstr = 10.1f; String longstr = 99999999; String dblstr = 99999999.9; int i = Integer.parseInt(intstr); /10float f = Float.parseFloat(fltstr); /10.1long lo = Long.parseLong(longstr); /99999999double d = Double.parseDouble(dblstr); /9.99999999E7Java实用教程(6) 从String转换到byte、short。例如:String

98、 str = 0; byte b = Byte.parseByte(str); /0short sh = Short.parseShort(str);/0Java实用教程(7) 从String转换到char。例如:String str = abc; char a = str.charAt(0);/返回字符a Java实用教程(8) 从String转换到boolean。例如:String str = true; Boolean flag = Boolean.valueOf(str);/trueJava实用教程3.3.6 StringBuffer类类 StringBuffer类提供了一个字符串的可

99、变序列,类似于String类,但它对存储的字符序列可以任意修改,使用起来比String类灵活得多。它常用的构造函数为: StringBuffer() 构造一个空StringBuffer对象,初始容量为16个字符。 StringBuffer(String str) 构造一个StringBuffer对象,初始内容为字符串str的拷贝。 对于StringBuffer类,除了String类中常用的像长度、字符串截取、字符串检索的方法可以使用之外,还有两个较为方便的方法系列,即append方法系列和insert方法系列。Java实用教程 (1) append方法系列根据参数的数据类型在StringBuf

100、fer对象的末尾直接进行数据添加。public StringBuffer append(boolean b) public StringBuffer append(char c) public StringBuffer append(char str) public StringBuffer append(char str, int offset, int len) public StringBuffer append(double d) public StringBuffer append(float f) public StringBuffer append(int i) public S

101、tringBuffer append(long l) public StringBuffer append(Object obj) public StringBuffer append(String str) public StringBuffer append(StringBuffer sb) Java实用教程 (2) insert方法系列根据参数的数据类型在StringBuffer的offset位置进行数据插入。public StringBuffer insert(int offset, boolean b) public StringBuffer insert(int offset, c

102、har c) public StringBuffer insert(int offset, char str) public StringBuffer insert(int index, char str, int offset, int len) public StringBuffer insert(int offset, double d) public StringBuffer insert(int offset, float f) public StringBuffer insert(int offset, int i) public StringBuffer insert(int o

103、ffset, long l) public StringBuffer insert(int offset, Object obj) public StringBuffer insert(int offset, String str) Java实用教程(3) 下面这个方法用于将stringbuffer对象的数据转换成字符串:public String toString() Java实用教程 【例3.12】基于例3.11进行修改,使用StringBuffer对象得到如图3.10所示的输出界面。/程序文件名为TestString.javapublic class TestStringpublic s

104、tatic void main(String args)StringBuffer str = new StringBuffer(The substring begins at the specified beginIndex.);StringBuffer str1 = new StringBuffer(string);String str2 = new String();int size = str.length();int flag = str.indexOf(substring);Java实用教程str2 = str.substring(flag,flag + 9);StringBuffe

105、r strOut = new StringBuffer(字符串);strOut.append(str);strOut.append(总长度为:);strOut.append(size);int f = strOut.indexOf(总);strOut.insert(f,n);System.out.println(strOut.toString();if(str1.toString().equals(str2) System.out.println(截取的字符串为: + str1.toString();else System.out.println(截取的字符串为: + str2); Java实

106、用教程3.3.7 StringTokenizer类类 StringTokenizer类是一个实现Enumeration接口的类,它使得应用程序可以将字符串分成多个记号,默认情况下以空格为分隔符,例如将字符串“this is a test”分成四个单词记号。用户也可以指定分隔符。分隔符为false,分割字符串;分隔符为true,则将分隔符自身作为分割后的字符串的一部分。其构造函数和常用方法如下: StringTokenizer(String str) 以字符串str构建StringTokenizer对象。Java实用教程StringTokenizer(String str, String del

107、im) 使用delim分隔符,以初始字符串str构建StringTokenizer对象。int countTokens() 返回识别的总记号数。boolean hasMoreTokens() 测试是否还有识别的记号。boolean nextToken(String delim) 返回字符串delim分隔的下一个记号。String nextToken() 返回下一个识别的记号。Java实用教程 【例3.13】使用StringTokenizer类分割字符串,字符串的分割情况如图3.11所示。源程序代码如下:import java.util.*;public class UseToken publi

108、c static void main(String args) String str = 数学:英语:语文:化学;StringTokenizer st = new StringTokenizer(str,:);System.out.println(str + n课程数为: +st.countTokens();Java实用教程while (st.hasMoreTokens() System.out.println(st.nextToken(:);str = Hello this is a test;st = new StringTokenizer(str);System.out.println(

109、str + n单词数为: +st.countTokens();while (st.hasMoreTokens() System.out.println(st.nextToken(); Java实用教程图3.11 StringTokenizer分割单词的结果输出Java实用教程习习 题题 1. 定义一个类Student,属性为学号、姓名和成绩;方法为增加记录SetRecord和得到记录GetRecord。SetRecord给出学号、姓名和成绩的赋值,GetRecord通过学号得到考生的成绩。 2. 给出上题中设计类的构造函数,要求初始化一条记录(学号、姓名、成绩)。 3. 假设一个学生所选课程为

110、语文、数学、英语、政治、物理、化学,给出此学生所选课程的Vector列表,并访问物理存放在Vector中的位置。Java实用教程 4. 对于图3.12中的Shebei表,将设备编码和设备名称作为Hashtable中的键和值进行存储,然后访问此Hashtable,找到键0008和0016并输出设备编码为0008、0016的设备名称。图3.12 习题3.4中的Shebei表Java实用教程 5. 编写程序,测试字符串“你好,欢迎来到Java世界”的长度,将字符串的长度转换成字符串进行输出,并对其中的“Java”四个字母进行截取,输出截取字母以及它在字符串中的位置。 6. 对于图3.12中的Sheb

111、ei表,将设备编码和设备名称用 : 进行连接,形成新的字符串,存储到Vector向量对象中,如0001:打印机、0008:书桌,然后访问Vector对象中设备编码为0010、0014的项,使用字符串操作的方法读取这两项设备编码对应的设备名称并输出。Java实用教程 7. 编写程序,测试150的阶乘所耗费的毫秒级时间。 8. 编写程序,将设备编码对应设备名称的记录添加到一个StringBuffer对象中,编码和名称之间用:隔开,每条记录之间用*隔开。 9. 编写程序,将字符串“打印机*钟表/自行车*雨伞%收音机?电脑”进行拆分,输出每个设备的名字。Java实用教程第4章 Java Applet

112、4.1 Applet简介简介 4.2 显示显示Applet 4.3 载入图片载入图片4.4 载入声音载入声音4.5 Applet控制浏览器环境控制浏览器环境4.6 服务器下配置服务器下配置Applet文件文件4.7 使用插件载入使用插件载入Applet4.8 JAR文件文件4.9 Applet和应用程序和应用程序习习 题题 Java实用教程4.1 Applet 简简 介介4.1.1 Applet的定义的定义 Applet是Java语言编写的,无法独立运行,但可以嵌入到网页中执行。它扩展了传统的编程结构和方法,可以通过互联网发布到任何具有Java编译环境浏览器的个体计算机上。Java实用教程4.

113、1.2 Applet的用途的用途 用户可以静态显示Applet,像显示一幅图片或者一段文本一样;Applet也可以是一个动态交互过程,用户输入简单的数据,就会产生相应的响应。Java实用教程4.1.3 Applet的编写格式的编写格式 编写Applet时,首先要引入java.applet包中的类,这个类里包含三个接口和Applet的类:import java.applet.*;import java.applet.Applet;类头定义为:public class MyApplet extends Applet;用来声明自定义类是从Applet类扩展而来的。Java实用教程 类体中没有应用程序

114、中必须具备的main方法,取而代之的是下面几个常用方法: public void init(); 初始化在这个方法中设置一些变量的初始化,像界面布局设置等。 public void start() 启动Applet开始执行。 public void stop() 停止Applet停止执行。 public void destroy() 撤消销毁Applet。Java实用教程【例4.1】编写Applet,显示系统的当前时间。源程序代码如下:/程序文件名UseApplet.javaimport java.awt.*;import java.applet.Applet;import java.util

115、.Date;public class UseApplet extends AppletString strTime = new String();public void init()Java实用教程public void start()Date d = new Date();strTime = d.toString();repaint();public void paint(Graphics g)g.drawString(当前时间为: + strTime,20,30);Java实用教程4.2 显显 示示 Applet4.2.1 工作流程工作流程 Applet是嵌入在HTML网页中显示的。首先从

116、服务器请求HTML网页,检测到Applet的类请求时,将所需类下载到本地,然后运行,其工作流程如图4.1所示。图4.1 客户端显示AppletJava实用教程 HTML页面中引用Applet的标签为,浏览器中执行Applet的步骤如下: (1) 浏览器请求HTML页面。 (2) 读HTML页面的过程中发现标签,然后继续向服务器请求标签中声明的类文件。 (3) 浏览器获取该类文件。 (4) 字节码验证这个类是否合法。 (5) 如果合法就开始执行类文件。 Java实用教程 有时可能需要载入多个类文件,直到将所有所需的类文件下载完毕为止。为上面的UseApplet.class类写一个最简单的网页Us

117、eApplet.html:Java实用教程图4.2 Applet输出时间Java实用教程图4.3 网页下显示输出时间的AppletJava实用教程4.2.2 参数设置参数设置 在HTML页面中嵌入Applet类文件时,可以在标签中设置属性以控制Applet类文件的外观显示,也可以传递一些用户自定义属性。嵌入的格式为:.Java实用教程其中: (1) 标签内为Applet的信息。 (2) 标记在之间进行设置,然后由Applet自带的方法获取。 (3) 标记有两个自己的属性:name和value。例如: (4) attribute1和attribute2的属性设置如表4.1所示。Java实用教程表

118、表4.1 属性设置及其描述属性设置及其描述Java实用教程 其中,code属性是必须的,height和width属性用来设置高度和宽度,如果都为0,那么Applet将隐藏。 对于例4.1中UseApplet.html,如果有 那么说明网页加载的类名为UseApplet.class,类显示的高度为200像素点,宽度为300像素点。 表4.1中列出的attibute1属性为定义的属性。用户还可以根据Applet程序的需要,传递一些程序自身属性,这些属性通过attribute2中name属性给出所需参数的名,value属性给出所需参数的值。public String getParameter(Str

119、ing name)Java实用教程 【例4.2】基于例4.1,在加载类的网页上设置一个用户名,使得Applet输出为“XXX,你好,当前时间为:(具体时间)”,如图4.4所示。源程序代码如下:/程序文件名UsePara.javaimport java.awt.*;import java.applet.Applet;import java.util.Date;public class UsePara extends AppletString strTime = new String();String strUser = new String();public void init()Java实用教

120、程/得到网页的参数:用户名strUser = getParameter(USER); public void start() Date d = new Date();strTime = d.toString();repaint(); public void paint(Graphics g) g.setColor(Color.red);g.drawString(strUser + 你好,当前时间为: + strTime,20,30); ;Java实用教程在UseApplet.html中添加一个用户参数设置:使修改后的网页程序如下:Java实用教程图4.4 网页设置参数后的Applet输出Jav

121、a实用教程放在浏览器中查看时,显示效果如图4.5所示。图4.5 浏览器中查看获取网页参数的Applet输出Java实用教程4.2.3 生命周期生命周期 Applet的生命周期是指Applet存在的时间,即某些方法还在被调用的时间。根据Applet的四个方法init()、start()、stop()、destroy(),可以得出Applet的生命周期,如图4.6所示。图4.6 Applet的生命周期Java实用教程4.3 载载 入入 图图 片片 在java.applet包中存在一个接口AppletStub。当一个Applet创建之后,一个Applet Stub使用setStub方法附加到Appl

122、et上,这个Stub用来充当Applet和浏览器环境之间的接口。在这个接口中一个重要的方法:public URL getDocumentBase()该方法返回的是Applet类文件所在网页的网络路径。例如,如果一个Applet类文件嵌入在下面网页中 http:/ http:/ 通过这个网络路径可以得到图片,从而由Applet类载入,载入图片的方法为: public Image getImage(URL url, String name)其中: (1) url给出图片所在的网路路径。 (2) name给出图片的名字。 例如:url路径可以为http:/ 【例4.3】编写Applet,载入Appl

123、et类文件所在路径下的图片index_01.gif,然后如图4.7所示显示图片。源程序代码如下:/程序文件名UseImage.javaimport java.awt.*;import java.applet.Applet;import .*;public class UseImage extends Applet/定义图像对象Image testImage;public void init()Java实用教程/得到图片testImage = getImage(getDocumentBase(),index_01.gif); public void paint(Graphics g) g.dra

124、wImage(testImage,0,0,this); 载入UseImage.class类的UseImage.html文件如下:Java实用教程图4.7 Applet载入图片显示Java实用教程4.4 载载 入入 声声 音音 Applet类提供一个用于载入声音的方法,即 public AudioClip getAudioClip(URL url, String name) 该方法返回由url和name决定的AudioClip对象。 其中: (1) url:音频剪辑的绝对URL地址; (2) name:相对于上面的url,为音频剪辑的相对地址,通常指名字。Java实用教程 【例例4.4】编写载入

125、声音的Applet。源程序代码如下:/程序文件名UseAudio.javaimport java.awt.*;import java.applet.Applet;public class UseAudio extends Appletpublic void init()public void start()/播放Applet所在目录下的tiger.au声音文件getAudioClip(getDocumentBase(),tiger.au).play();Java实用教程 ;载入类的HTML文件如下:/applet 在浏览器加载或者appletviewer命令启动时可以听见老虎的叫声,但必须保证

126、tiger.au在UseAudio.class类文件所在的目录。Java实用教程4.5 Applet控制浏览器环境控制浏览器环境 java.applet包中提供一个接口AppletContext,对应着Applet的环境,主要指包含Applet的网页文档等,在这个接口内有两个重要方法:pubilc void showDocument(URL url) 浏览器下载Applet时,showDocument可以将当前Applet页面用于显示url网址的内容。 url 给出页面的绝对网络路径。 public void showDocument(URL url, String target) targe

127、t可以表明url显示的位置,有四种情况,如表4.2所示。Java实用教程表表4.2 target 取取 值值public void showStatus(String status)字符串status显示在状态栏中,告知用户当前类文件运行中的状态。Java实用教程 【例4.5】编写Applet,在状态栏显示鼠标单击Applet的次数,结果如图4.8所示。源程序代码如下:/程序文件名ShowStatus.javaimport java.applet.*;import java.applet.Applet;import java.awt.event.*;public class ShowStatu

128、s extends Appletint count = 0;public void init()Java实用教程public boolean mouseClicked(MouseEvent e)count +;getAppletContext().showStatus(你好,你已经点击了 + count + 次了!);return true;Java实用教程图4.8 状态栏显示单击次数信息Java实用教程 【例4.6】编写Applet,在一个框架中显示不同来源的网页信息,如图4.9所示。左框架为西安交通大学首页,右框架为新浪网首页。源程序代码如下:/程序文件名ShowHtml.javaimpo

129、rt java.applet.*;import java.applet.Applet;import .URL;public class ShowHtml extends Appletpublic void init()Java实用教程 public void start() try/创建URL对象URL urlName=new URL(http:/);/在左框架显示网页getAppletContext().showDocument(urlName,left);urlName = new URL(http:/);/右框架显示网页getAppletContext().showDocument(ur

130、lName,right);Java实用教程 catch(MalformedURLException e) System.out.println(e.getMessage(); 载入Applet的网页Head.html的代码如下:Java实用教程这是一个框架网页,上面的框架隐藏载入applet类文件,由applet控制左框架显示西安交通大学的主页,右框架显示新浪网的主页。装配的框架网页ShowHtml.html的源代码如下,可以看见其中框架名字左边的为left而右边的为right。Java实用教程 Java实用教程图4.9 框架网页显示Java实用教程4.6 服务器下配置服务器下配置Applet

131、文件文件 由于Applet文件是客户端浏览器从服务器端下载的HTML网页,所以将文件配置到服务器端,由客户进行访问。 本机中使用的服务器为Tomcat 4.0,安装成功后重启动,则服务器开始运转,在浏览器的网址栏键入http:/192.100.100.43:8080/index.html,如果出现如图4.10所示的Tomcat主网页,则证明服务器测试正常。Java实用教程图4.10 Tomcat主页Java实用教程 配置自己的文件时,推荐在安装目录D:Apache Tomcat 4.0webappsROOT下建立自己的文件夹,这样有利于管理。本书作者在此文件夹下建立user目录,以为载入图片的

132、Applet为例,将UseImage.html、UseImage.class和Image_01.gif拷贝到user目录下,并在IE浏览器的地址栏键入网址:http:/192.100.100.43:8080/user/UseImage.html,浏览器显示结果如图4.11所示,与前面例4.3中图4.7载入的图片效果一致,但可以看出地址栏的网址不同。Java实用教程图4.11 配置到服务器端的网页显示Java实用教程4.7 使用插件载入使用插件载入Applet Java插件(Plug-in)扩展了网络浏览器的功能,使得无论在哪个浏览器(IE浏览器或者Netscape浏览器)下,Java Appl

133、et可在Sun的Java运行环境(JRE)下运行,而不是在浏览器自带的JRE环境下运行。Java插件是Sun的JRE环境的一部分,当安装JRE时,插件自动安装。当你安装J2sdk-1.4.0_01时,JRE环境版本号也为1.4.0_01。使用插件最大的不同是将IE浏览器中网页原有的标签改成了标签,在Netscape中则改成,这里只讨论IE浏览器中的使用。Java实用教程 J2sdk1.4提供了一个叫做HtmlConverter的工具,用于将包含普通标签的HTML文件转换成包含对象的文件。在命令行提示符键入命令HtmlConverter后按回车键,出现如图4.12所示对话框。 其中: (1) “

134、指定文件”为要转换的文件。 (2) “模板文件”为操作系统和浏览器适用类型,操作系统有Windows和Solaris,浏览器分为IE和Netscape。本书选择适用于Windows和Solaris的IE浏览器。Java实用教程 (3) 在“适用于小应用程序的Java版本”栏中选中第一项“只适用于Java1.4.0_01”,这是因为作者使用的JDK安装版本为Java1.4.0_01。 将这几项进行设置之后,单击“转换”按钮,则将原有的UseImage.html文件内容转换为:Java实用教程!-Java实用教程图4.12 HtmlConverter工具界面Java实用教程其中codebase=h

135、ttp:/ 0, 10表示如果客户端浏览器不存在此插件,可以从codebase指定的网址下载,由上述语句行可以看出HtmlConverter生成的插件文件的插件下载地址为Sun公司的网站。如果本机上放置了插件的安装程序,那么此处可以改为从本机下载,以加快下载速度。如果在网站上发布你的Applet的网页,建议使用插件方式载入Applet,可以与多种浏览器兼容。Java实用教程4.8 JAR 文文 件件4.8.1 操作操作JAR文件文件 在JDK的安装目录的bin子目录下有一个jar.exe文件,这就是JAR文件的操作工具,用它及一系列选项来实现对JAR文件的操作。jar命令的格式如下:jar c

136、txuvfm0M jar-文件 manifest-文件 -C 目录 文件名 .Java实用教程其中:(1) ctxu四者必选其一,各选项的含义如下: -c 创建新的存档; -t 列出存档内容的列表; -x 展开存档中命名的(或所有的)文件; -u 更新已存在的存档。Java实用教程(2) vfm0M为可选项,各选项的含义如下: -v 生成详细输出到标准输出上; -f 指定存档文件名; -m 包含来自标明文件的标明信息; -0 只存储方式,未用ZIP压缩格式; -M 不产生所有项的清单(manifest)文件; -C 改变到指定的目录,并且包含下列文件。Java实用教程 (3) 清单(manif

137、est)文件名和存档文件名都需要指定,指定的顺序依照命令行中“m”和“f”标志的顺序。 例如: 将两个class文件存档到一个名为“classes.jar”的存档文件中: jar cvf classes.jar Foo.class Bar.class 用一个存在的清单(manifest)文件“mymanifest”将foo/目录下的所有文件存档到一个名为“classes.jar”的存档文件中: jar cvfm classes.jar mymanifest -C foo/ . 对JAR文件常用的操作有三种:创建JAR文件、列出JAR文件和抽取JAR文件。Java实用教程 1. 创建创建JAR文

138、件文件 jar cvf UseImage.jar UseImage.class index_01.gif 当用JAR工具创建新的档案时,自动增加一个声明文件到文档中。如果用户需要创建自己的声明文件时,则指定m选项。可以看到本目录下多了一个UseImage.jar文件。创建JAR文件的过程如图4.13所示。图4.13 创建JAR文件Java实用教程2. 列出列出JAR文件的内容文件的内容jar tvf UseImage.jar执行命令后列出JAR文件中的内容,如图4.14所示。图4.14 列出JAR文件Java实用教程 3. 抽取抽取JAR文件文件 jar xvf UseImage.jar 抽取

139、JAR文件是将JAR中包含的类以及相关文件逐一恢复。在E:_WorkJavasample目录下建立JAR文件夹,将JAR文件放入此文件夹,然后进行抽取,可以看见JAR目录下除了UseImage.class和index_01.gif,还有META-INF子目录,下面有一个文件MANIFEST.MF。图4.15给出抽取JAR文件的过程。 Java实用教程图4.15 抽取JAR文件Java实用教程4.8.2 客户端使用客户端使用JAR文件文件 标签中添加一个属性名字为archive,它的值为要载入的.jar文件。例如archive=UseImage.jar。 例如,将D:Apache Tomcat

140、4.0webappsROOTuserUseImage.html文件代码改为:Java实用教程4.9 Applet和应用程序和应用程序 【例4.7】修改例4.1的Applet,使得它可以从命令提示符状态下访问。 (1) 基于例4.1的UseApplet添加一个main方法如下:public static void main(String args)/创建一个框架Frame f = new Frame(时间);/关闭窗口时退出系统f.addWindowListener(new WindowAdapter()Java实用教程public void windowClosing(WindowEvent

141、evt)System.exit(0););/创建一个AppletApp对象AppletApp a = new AppletApp();/将对象载入框架f.add(Center,a);/设置框架大小f.setSize(300,200);/显示框架Java实用教程f.show();/初始化对象a.init();/启动对象a.start();Java实用教程(2) 修改后的源程序代码如下:/程序文件名AppletApp.javaimport java.awt.*;import java.awt.event.*;import java.applet.Applet;import java.util.Da

142、te;public class AppletApp extends AppletString strTime = new String();public void init()Java实用教程public void start()Date d = new Date();strTime = d.toString();repaint();public void paint(Graphics g)g.drawString(当前时间为: + strTime,20,30);public static void main(String args)Java实用教程/创建一个框架Frame f = new F

143、rame(时间);/关闭窗口时退出系统f.addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent evt)System.exit(0););/创建一个AppletApp对象AppletApp a = new AppletApp();Java实用教程a.init();/将对象载入框架f.add(Center,a);f.setSize(200,400);f.show();a.start(); ;Java实用教程 (3) 编译通过并生成UseApplet.class类后,在命令提示符状态下键入“java U

144、seApplet”,得到如图4.2所示的时间输出界面。Java实用教程 【例4.8】修改例4.2,在命令提示符状态下输入用户名参数,使得可以在命令提示符状态下进行访问。 (1) 从命令行状态输入用户名参数,应用程序的读取如下:if (args.length 1)System.out.println(缺少用户参数);System.exit(0);elsestrUser = new String(args0);Java实用教程 (2) 添加一个变量static boolean inApplet = true; 用于控制取参数的方式,如果以应用程序调用,则从命令行取参数;如果是载入Applet,则从

145、网页中取参数。Java实用教程(3) 源程序代码如下:/程序文件名AppPara.javaimport java.awt.*;import java.awt.event.*;import java.applet.Applet;import java.util.Date;public class AppPara extends AppletString strTime = new String();static String strUser = new String();static boolean inApplet = true;public void init()Java实用教程/如果从Ap

146、plet载入,从网页得到参数if(inApplet)strUser = getParameter(USER);public void start()Date d = new Date();strTime = d.toString();repaint();public void paint(Graphics g)Java实用教程 g.setColor(Color.red); g.drawString(strUser + 你好,当前时间为: + strTime,20,30);public static void main(String args) inApplet = false; /如果从命令行

147、提示符状态进入,获取参数 if (args.length 1) System.out.println(缺少用户参数);System.exit(0); elseJava实用教程strUser = new String(args0);/创建一个框架Frame f = new Frame(时间);/关闭窗口时退出系统f.addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent evt)System.exit(0););/创建一个AppletApp对象AppPara a = new AppPara();Java

148、实用教程/初始化a.init();/将对象载入框架f.add(Center,a);/设置框架大小f.setSize(400,200);/显示框架f.show();/启动对象a.start(); Java实用教程 (4) 在命令提示符状态键入命令“java AppPara 王飞”后按回车键,弹出如图4.5所示的界面。 Java实用教程习习 题题 1. 编写Applet,载入图片的同时响起音乐。 2. 将上题的Applet类、图片文件、音乐文件进行压缩并生成JAR文件,然后载入运行。Java实用教程 3. 编写程序,既可用作Applet,又可用作应用程序,在出现的界面中显示下面的内容,括号内表示显

149、示的颜色。特点:(蓝色显示)(1) 跨平台性(以下均为红色显示)(2) 面向对象(3) 安全性(4) 多线程(5) 简单易用Java实用教程 4. 在上题的基础上,输入参数“Java语言”,使得显示内容如下所示,要求既可以从命令行输入,也可以从网页内输入。Java语言特点:(1) 跨平台性(2) 面向对象(3) 安全性(4) 多线程(5) 简单易用Java实用教程第5章 Java图形处理 5.1 Java图形图形5.2 Paint方法、方法、Update方法和方法和Repaint方法方法5.3 Graphics类类5.4 Color类类5.5 Graphics2D类类 习习 题题 Java实用

150、教程5.1 Java图形图形 抽象窗口化工具(AWT)为图形用户界面编程提供API编程接口,使得Java可以提供较好的图形用户界面。AWT把图形处理分为两个层次:一是处理原始图形,这一层较原始,图形直接以点、线和面的形式画到界面上;二是提供大量组件,实现可定制的图形用户界面。本章主要讨论如何在界面上画图形及所画图形的特征。Java编程语言中的图形坐标系统不同于数学中的坐标系,屏幕左上角为(0,0),右下角为屏幕水平向右和垂直向下增长的像素数。Java实用教程5.2 Paint方法、方法、Update方法和方法和Repaint方法方法 1. Paint方法方法 public void paint

151、(Graphics g) 以画布为参数,在画布上执行画图方法。在Applet中,不显式地调用paint方法。 2. Repaint方法方法 Applet重画时系统自动调用paint方法。 3. Update方法方法 public void update(Graphics g) 更新容器,向Repaint发出刷新小应用程序的信号,缺省的Update方法清除Applet画图区并调用Paint方法。Java实用教程5.3 Graphics类类 Graphics类是所有图形上下文的抽象基类,允许应用程序在各种设备上实现组件的画图。图形对象封装了Java支持的基本渲染操作的状态信息,包括画图的组件对象、

152、渲染区域的坐标(coordinates)、区域(clip)、颜色(color)、字体(font)、画图模式等。Graphics类提供画各种图形的方法,其中包括线、圆和椭圆、矩形和多边形、图像以及各种字体的文本等。这些方法具体如下: public abstract void clipRect(int x, int y, int width, int height) 指定的区域切分。Java实用教程public abstract void drawLine(int x1, int y1, int x2, int y2) 使用当前颜色,在点(x1, y1) 和 (x2, y2) 之间画线。publi

153、c abstract void drawOval(int x, int y, int width, int height) 画椭圆。public abstract void fillOval(int x, int y, int width, int height) 画实心椭圆。public abstract void drawPolygon(int xPoints, int yPoints, int nPoints) 画x和y坐标定义的多边形。Java实用教程public void drawRect(int x, int y, int width, int height) 画矩形。public

154、 void drawRect(int x, int y, int width, int height) 画实心矩形。public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 使用当前颜色画圆角矩形。public abstract void drawString(String str, int x, int y) 使用当前字体和颜色画字符串str。Java实用教程public abstract void setColor(Color c) 设置图形上下文

155、的当前颜色。public abstract void setPaintMode() 设置画模式。public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer) 画特定图。public abstract void setFont(Font font) 设置特定的font字体。使用时首先得到font对象的一个实例,Font类常用构造函数为:public Font(String name, int style, int size) Java实用教程 通过指定的name、style和size创建字体实

156、例。name指字体名,像“隶书”、“TimesRoman”等,字体风格为粗体、斜体,size指字号大小。 例如:Font f = new Font(TimesRoman,Font.BOLD + Font.ITALIC, 12);创建了具有粗斜体风格的12磅的TimesRoman字体。 Java实用教程 【例5.1】设置Graphics对象画图,显示结果如图5.1所示。源程序代码如下:/程序文件名SimpleGUI.javaimport java.awt.*;import java.applet.*;public class SimpleGUI extends AppletImage samIm

157、age;public void init() samImage=getImage(getDocumentBase(),sample.gif);Java实用教程public void paint(Graphics g)/g.clipRect(50,50,180,180);/画线g.drawLine(0,0,20,30);/输出字符串g.drawString(图形显示,100,30);/设置颜色Color c = new Color(255,200,0);g.setColor(c);/设置字体Java实用教程Font f = new Font(TimesRoman,Font.BOLD+ Font.

158、ITALIC,24);g.setFont(f);g.drawString(图形显示,180,30);g.drawLine(20,20,100,50);g.drawLine(20,20,50,100);/矩形g.drawRect(40,40,40,40);g.fillRect(60,60,40,40);g.setColor(Color.red);/3D矩形g.draw3DRect(80,80,40,40,true);Java实用教程g.draw3DRect(100,100,40,40,false);g.fill3DRect(120,120,40,40,true);/椭圆g.drawOval(15

159、0,150,30,40);g.fillOval(170,170,20,20);g.setColor(Color.blue);/圆角矩形g.drawRoundRect(180,180,40,40,20,20);g.fillRoundRect(200,200,40,40,20,20);Java实用教程/多边形int xC = 242,260,254,297,242;int yC = 240,243,290,300,270;g.drawPolygon(xC,yC,5);/图片g.drawImage(samImage,250,50,this);Java实用教程图5.1 简单的图形界面Java实用教程将

160、例5.1注释的程序语句/ g.clipRect(50,50,180,180);的注释符号去掉,重新编译执行,可以看见如图5.2所示的结果。图图5.2 裁剪后的图形界面裁剪后的图形界面Java实用教程5.4 Color类类 Color类是用来封装颜色的,在上面的例子中多次用到。使用Color对象较为简单的方法是直接使用Color类提供的预定义的颜色,像红色Color.red、橙色Color.orange等;也可以使用RGB颜色模式进行定义。所谓RGB颜色模式是指使用三种基色:红、绿、蓝,通过三种颜色的调整得出其它各种颜色,这三种基色的值范围为0255。例如Color c = new Color(

161、255,200,0);定义橙色。表5.1给出常用颜色的RGB值以及对应的类预定义参数。Java实用教程表表5.1 常用颜色的常用颜色的RGB值以及对应的类预定义参数值以及对应的类预定义参数Java实用教程 Color还有一个构造函数,它构造的Color对象用于是否透明显示颜色。 public Color(int red, int green, int blue, int alpha) 其中:前三个分量即RGB颜色模式中的参数,第四个alpha分量指透明的程度。当alpha分量为255时,表示完全不透明,正常显示;当alpha分量为0时,表示完全透明,前三个分量不起作用,而介于0255之间的值可

162、以制造出颜色不同的层次效果。Java实用教程【例例5.2】测试Color对象,界面如图5.3所示。源程序代码如下:/程序文件名UseColor.javaimport java.awt.*;import java.applet.*;import java.awt.geom.*;public class UseColor extends Appletpublic void paint(Graphics oldg) Graphics2D g = (Graphics2D)oldg;Java实用教程g.setColor(Color.blue);g.fill(new Ellipse2D.Float(50,

163、50,150,150);g.setColor(new Color(255,0,0,0);g.fill(new Ellipse2D.Float(50,50,140,140);g.setColor(new Color(255,0,0,64);g.fill(new Ellipse2D.Float(50,50,130,130);g.setColor(new Color(255,0,0,128);g.fill(new Ellipse2D.Float(50,50,110,110); g.setColor(new Color(255,0,0,255);g.fill(new Ellipse2D.Float(5

164、0,50,90,90);g.setColor(new Color(255,200,0);g.fill(new Ellipse2D.Float(50,50,70,70);Java实用教程图5.3 颜色测试界面Java实用教程5.5 Graphics2D类类 Graphics2D类继承于Graphics类,提供几何学、坐标变换、颜色管理以及文本排列等的更高级控制。Graphics2D类是Java平台上渲染二维图形、文字、以及图片的基础类,提供较好的对绘制形状、填充形状、旋转形状、绘制文本、绘制图像以及定义颜色的支持。 在AWT编程接口中,用户通过Paint方法接收Graphics对象作为参数,若是

165、使用Graphics2D类,就需要在Paint方法中进行强制转换。Public void paint(Graphics old)Graphics2D new = (Graphics2D)old;Java实用教程5.5.1 绘制形状绘制形状 Graphics2D提供以下两个方法进行形状的绘制: public abstract void draw(Shape s) 根据Graphics2D的环境设置画出形状s,其中Shape接口包含的类如表5.2所示。 public abstract void fill(Shape s) 画实心形状s。Java实用教程表表5.2 Graphics2D绘制的图形类绘

166、制的图形类Java实用教程其中GeneralPath是一般的几何路径,它的构造函数为:public GeneralPath()构造一个空的对象。常用的方法有四个,分别如下:public void lineTo(float x, float y) 从当前坐标点到(x,y)坐标点画一条直线,将此点添加到路径上。public void moveTo(float x, float y) 移动到坐标点(x,y),在路径上添加此点。 Java实用教程 public void quadTo(float x1, float y1, float x2, float y2) 以坐标点(x1,y1)为控制点,在当前

167、坐标点和坐标点(x2,y2)之间插入二次曲线片断。 public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) 以(x1,y1)和(x2,y2)为控制点,在当前坐标点和(x3,y3)之间插入曲线片断。 Java实用教程 在Draw方法中提到Graphics2D的环境设置。所谓的环境设置是指设置画图的笔画和填充属性等,设置方法分别如下: public abstract void setStroke(Stroke s) 设置笔画的粗细。其中Stroke接口中常用BasicStroke类来实现,一个较

168、简单的构造函数为 public BasicStroke(float width) 创建实线笔画宽度为width。 public abstract void setPaint(Paint paint)Java实用教程 设置Graphics2D环境的填充属性。其中,paint的值可以为渐变填充类java.awt.GradientPaint,也可以为图形填充类java.awt.TexturePaint,后者将在5.5.3节绘制图像中讲到。渐变填充类常用构造函数为 public GradientPaint(float x1, float y1, Color color1, float x2, floa

169、t y2, Color color2, boolean cyclic) 构建一个渐变GradientPaint对象,在起始坐标点到目标坐标点之间从颜色color1到color2渐变,cyclic为真,循环渐变。Java实用教程 【例5.3】演示了几何形状、笔画变换以及颜色渐变显示。其中直线的笔画宽度为10,其它笔画宽度为5,中间三个图形实现绿色到蓝色的循环渐变,后三个图形实现红色到黄色的循环渐变,如图5.4所示。/程序文件名GUI2D.javaimport java.awt.*;import java.applet.*;import java.awt.geom.*;public class G

170、UI2D extends AppletJava实用教程public void paint(Graphics oldg)Graphics2D g = (Graphics2D)oldg;/设置笔画宽度BasicStroke stroke = new BasicStroke(10);g.setStroke(stroke);/画线Line2D line = new Line2D.Float(0,0,20,30);g.draw(line);line = new Line2D.Float(50,50,100,50);g.draw(line);Java实用教程line = new Line2D.Float(

171、50,50,50,100);g.draw(line);stroke = new BasicStroke(5);g.setStroke(stroke);/设置渐变填充GradientPaint gt = new GradientPaint(0,0,Color.green,50,30,Color.blue,true);g.setPaint(Paint)gt);/画矩形Rectangle2D rect = new Rectangle2D.Float(80,80,40,40);Java实用教程g.draw(rect);rect = new Rectangle2D.Float(100,100,40,40

172、);g.fill(rect);/画椭圆Ellipse2D ellipse = new Ellipse2D.Float(120,120,30,40);g.draw(ellipse);gt = new GradientPaint(0,0,Color.red,30,30,Color.yellow,true);g.setPaint(Paint)gt);ellipse = new Ellipse2D.Float(140,140,20,20);g.fill(ellipse);Java实用教程/画圆角矩形RoundRectangle2D roundRect = new RoundRectangle2D.Fl

173、oat(160,160,40,40,20,20);g.draw(roundRect);roundRect = new RoundRectangle2D.Float(180,180,40,40,20,20);g.fill(roundRect);/画几何图形GeneralPath path = new GeneralPath();path.moveTo(150,0);path.lineTo(160,50);path.curveTo(190,200,240,140,200,100);g.fill(path); Java实用教程图5.4 通过Graphics2D对象绘制形状Java实用教程5.5.2

174、绘制文本绘制文本 Graphics2D类提供一个文本布局(TextLayout)对象,用于实现各种字体或段落文本的绘制。其构造函数为: public TextLayout(String string, Font font, FontRenderContext frc) 通过字符串string和字体font构造布局。 public void draw(Graphics2D g2, float x, float y) 将这个TextLayout对象画到Graphics2D对象g2上的x,y坐标处。 public Rectangle2D getBounds() 返回TextLayout对象的区域。J

175、ava实用教程【例5.4】测试绘制文本功能,如图5.5所示。源程序代码如下:/程序文件GUIText.javaimport java.awt.*;import java.applet.*;import java.awt.geom.*;import java.awt.font.*;public class GUIText extends Appletpublic void paint(Graphics oldg)Java实用教程Graphics2D g = (Graphics2D)oldg;/设置字体Font f1 = new Font(Courier,Font.PLAIN,24);Font f

176、2 = new Font(helvetica,Font.BOLD,24);FontRenderContext frc = g.getFontRenderContext();String str = new String(这是一个文本布局类的实现);String str2 = new String(扩充绘制文本的功能);/构造文本布局对象TextLayout layout = new TextLayout(str, f1, frc);Point2D loc = new Point2D.Float(20,50);Java实用教程/绘制文本layout.draw(g, (float)loc.getX

177、(), (float)loc.getY();/设置边框Rectangle2D bounds = layout.getBounds();bounds.setRect(bounds.getX()+loc.getX(), bounds.getY()+loc.getY(), bounds.getWidth(), bounds.getHeight();g.draw(bounds);layout = new TextLayout(str2,f2,frc);g.setColor(Color.red);layout.draw(g,20,80); Java实用教程图5.5 Graphics2D对象绘制文本Jav

178、a实用教程5.5.3 绘制图像绘制图像 绘制图像用到BufferedImage类,BufferedImage类是指存放图像数据的可访问的缓冲。其构造函数为: public BufferedImage(int width, int height, int imageType) 使用宽度(width)、高度(height)和imageType类型构造BufferedImage对象。 public Graphics2D createGraphics() Java实用教程用图片填充椭圆的具体过程如下:(1) 创建一个Graphics2D,可以画到BufferedImage中。例如构建一个Buffere

179、dImage对象buf。BufferedImage buf = new BufferedImage (img.getWidth(this),img.getHeight(this),BufferedImage.TYPE_INT_ARGB);创建一个临时Graphics2D对象:Graphics tmpG = buf.createGraphics();将图像画入临时缓冲:tmpG.drawImage(img,10,10,this);Java实用教程(2) 用TexturePaint类进行填充:public TexturePaint(BufferedImage txtr, Rectangle2D a

180、nchor)构造TexturePaint对象,需要一个Rectangle2D对象来存放该对象:Rectangle2D rect = new Rectangle2D.Float(0,0,h,w);TexturePaint t = new TexturePaint(buf,rect);(3) 然后设置填充模式,并进行填充:g.setPaint(t);g.fill(new Ellipse2D.Float(100,50,60,60);Java实用教程 【例5.5】完成图像显示,并将区域蓝色透明显示,然后进行图片填充,如图5.6所示。源程序代码如下:/程序文件名GUIImage.javaimport j

181、ava.awt.*;import java.applet.*;import java.awt.geom.*;import java.awt.font.*;import java.awt.image.*;import .*;Java实用教程public class GUIImage extends Applet public void paint(Graphics oldg) Graphics2D g = (Graphics2D)oldg;tryURL imgURL = new URL(getDocumentBase(),sample.gif);Image img = getImage(imgU

182、RL);int h = img.getHeight(this);int w = img.getWidth(this);Java实用教程/构造缓冲图像对象BufferedImage buf = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);/放入临时图形类Graphics tmpG = buf.createGraphics();tmpG.drawImage(img,10,10,this);g.drawImage(buf,10,20,this);/设置透明颜色对象 Color transBlue = new Color(0,0,255,100

183、);g.setColor(transBlue);GeneralPath path = new GeneralPath();Java实用教程path.moveTo(60,0);path.lineTo(50,100);path.curveTo(160,230,240,140,200,100);g.fill(path);transBlue = new Color(0,0,255,240);g.fill(new Ellipse2D.Float(100,100,50,50);Rectangle2D rect = new Rectangle2D.Float(0,0,h,w);/图片填充TexturePai

184、nt t = new TexturePaint(buf,rect);Java实用教程g.setPaint(t);g.fill(new Ellipse2D.Float(100,50,60,60);catch(Exception e)System.out.println(Error: + e.getMessage(); Java实用教程图5.6 通过Graphics2D对象绘制图像Java实用教程习习 题题 1. 使用Graphics类进行图形绘制,要求绘制深蓝色矩形和红色椭圆形,然后分别进行填充。 2. 使用Graphics2D类绘制粉红色到蓝色的渐变,填充到圆角矩形、多边形,笔画宽度为10。

185、3. 绘制文本“欢迎来到Java世界”,其中“欢迎来到”为蓝色显示,而“Java世界”为橙色显示,文本用矩形框起来,底色为黄色。 4. 画一个三角形区域,然后用图片进行填充。Java实用教程第6章 Java用户界面技术 6.1 用户界面对象用户界面对象 6.2 布局布局 6.3 java.swing包包 习习 题题 Java实用教程6.1 用户界面对象用户界面对象 用户界面上经常用到的组件对象有Button(按钮)、Checkbox(复选框)、Choice(组合框)、Label(标签)、List(列表)、Scrollbar(滚动条)、TextComponent(TextArea(文本区域)、T

186、extField(文本框)和Panel(面板)。这些组件类的继承情况如下:java.lang.Object | +-java.awt.BorderLayout +-java.awt.FlowLayout +-java.awt.ComponentJava实用教程 | +-java.awt.Button +-java.awt.Canvas+-java.awt.Checkbox+-java.awt.Choice+-java.awt.Container|+-java.awt.Panel+-java.awt.Label+-java.awt.List+-java.awt.Scrollbar+-java.a

187、wt.TextComponent | +-java.awt.TextArea +-java.awt.TextFieldJava实用教程6.1.1 按钮按钮 Button类创建一个带标签的按钮对象,当按下一个按钮时,可以引发一些事件,包含一系列的动作或操作。例如单击按钮,使得界面颜色发生变化等。它的构造函数以及主要的方法如下:public Button() 构建一个没有标签的按钮。public Button(String label) 构建一个显示为label的按钮。public void setLabel(String label)设置显示标签为字符串label。public String g

188、etLabel()获取按钮的标签,返回为字符串。Java实用教程 【例6.1】测试Button类的Applet。用户界面如图6.1所示。源程序代码如下:/程序文件名UseButton.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UseButton extends AppletString str1 = new String(); /声明按钮对象Button b1; Button b2;Java实用教程public void init() /构造对象 b1 = new Butt

189、on(); b2 = new Button(按钮对象2); /添加到界面 this.add(b1); this.add(b2);public void start()Java实用教程b1.setLabel(按钮对象1);str1 = b2.getLabel();repaint();public void paint(Graphics g)g.drawString(str1,20,30);Java实用教程启动Applet的HTML页面代码如下:Java实用教程图6.1 测试Button类的界面Java实用教程6.1.2 复选框和单选按钮复选框和单选按钮 复选框是一个图形组件,有两个状态,即“选中

190、”(true)和“未选中”(false)。单击复选框时可以在“选中”、“未选中”之间进行切换。在Java编程语言中,单选按钮没有单独的类,而是作为复选框的特例存在,用户通过把一组复选框放置在同一个复选框组中创建一套单选按钮。它的构造函数和其它方法如下:public Checkbox() 创建一个没有标签的复选框。public Checkbox(String label) 创建一个标签为lable的复选框。Java实用教程 public Checkbox(String label, boolean state) 创建一个标签为lable的复选框,并设置初始状态。 public CheckboxG

191、roup() 创建一个复选框组,用来放置单选按钮。 public Checkbox(String label, CheckboxGroup group, boolean state) 创建一个标签为lable的复选框,添加到group组中并设置初始状态,作为单选按钮的形式出现。Java实用教程public String getLabel()获得复选框的标签。public void setLabel(String label)设置标签。public boolean getState()返回复选框所在的状态,是选中还是未选中。public void setState(boolean state)设

192、置状态,用来初始化复选框的状态。Java实用教程 【例6.2】测试复选框和单选按钮的用法,用户界面如图6.2所示。源程序代码如下:/程序文件名UseCheckbox.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UseCheckbox extends AppletString str1 = new String();boolean b1 = false;boolean b2 = false;Java实用教程Checkbox c1,c2,c3;Checkbox cRadio1,c

193、Radio2;CheckboxGroup c;public void init() c1 = new Checkbox(); c2 = new Checkbox(复选框对象2); c3 = new Checkbox(复选框对象3,true); /构造单选按钮 c = new CheckboxGroup(); cRadio1 = new Checkbox(单选按钮1,c, false);Java实用教程cRadio2 = new Checkbox(单选按钮2,c,true); /添加到界面 this.add(c1); this.add(c2); this.add(c3); this.add(cR

194、adio1); this.add(cRadio2);public void start()c1.setLabel(复选框对象1);Java实用教程str1 = c2.getLabel();b1 = c3.getState();b2 = cRadio1.getState();repaint();public void paint(Graphics g)g.drawString(获取第二个对象的标签: + str1,40,80);g.drawString(复选框3的状态为: + b1,40,100);g.drawString(单选按钮1的状态为: + b2, 40,120);Java实用教程图6.

195、2 复选框和单选按钮测试Java实用教程6.1.3 组合框组合框 组合框代表一系列选择的弹出式菜单,当前选择显示为菜单的标题。它的构造函数和其它常用方法如下: public Choice() 构建一个选择项菜单。 public void add(String item) 将item添加到选择菜单中。 public String getItem(int index) 返回选择菜单中index位置的项,注意索引是从0开始的,而项数从1开始。Java实用教程public int getItemCount()返回选择菜单总的项数。public String getSelectedItem()返回当前选

196、中的项。 public int getSelectedIndex()返回当前选中项的索引。 public void insert(String item, int index)在index处插入字符串item。public void remove(int position)删除position位置的项。Java实用教程public void remove(String item)删除item项。public void removeAll()删除所有的项。public void select(int pos)将pos处的项设为选中状态,通常用于初始化。 public void select(St

197、ring str)将str项设为选中状态,通常用于初始化。Java实用教程【例6.3】测试Choice类,用户界面如图6.3所示。源程序代码如下:/程序文件名UseChoice.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UseChoice extends AppletString str1 = new String();String str2 = new String();int count = 0;int i1 = 0;Java实用教程boolean b1 = false

198、;Choice c1;/声明组合框对象public void init() /初始化组合框对象, c1 = new Choice(); c1.add(语文); c1.add(数学); c1.add(物理); c1.add(化学); c1.add(生物); c1.select(3); this.add(c1);Java实用教程 public void start() count = c1.getItemCount();str1 = c1.getItem(2); str2 = c1.getSelectedItem();i1 = c1.getSelectedIndex();repaint(); pu

199、blic void paint(Graphics g) g.drawString(元素总个数为: + count,10,80);g.drawString(第2项元素为: + str1,10,100);g.drawString(选中项的元素为: + str2,10,120);g.drawString(选中项的位置为: + i1,10,140); ; Java实用教程图6.3 测试Choice实例的用户界面Java实用教程在上例的基础上添加一个方法operate,并在start方法中调用此方法,程序段如下:public void operate()c1.insert(英语,3);c1.remove

200、(生物);public void start()operate();count = c1.getItemCount();.Java实用教程图6.4 修改操作后的用户界面Java实用教程6.1.4 标签标签 标签对象就是将文本放入一个容器内的组件,显示一行只读文本。文本可以由程序修改,用户无法直接修改。它的构造函数和其它常用方法如下:public Label() 构建一个空标签。 public Label(String text) 构建一个text内容的标签,默认为左对齐。public Label(String text, int alignment) Java实用教程 构建一个内容为text,

201、以alignment方式对齐的标签,其中alignment的取值如表6.1所示。表表6.1 标签标签alignment的属性取值的属性取值Java实用教程public String getText()获得标签文本。public void setText(String text)设置标签文本。public int getAlignment()获得标签文本对齐方式,返回为整型值。Java实用教程【例6.4】测试Label类,用户界面如图6.5所示。源程序代码如下:/程序文件名UseLabel.javaimport java.awt.*;import java.applet.*;import jav

202、a.applet.Applet;public class UseLabel extends AppletString str1 = new String();int i1 = 0;Label l1;/声明对象Label l2;Java实用教程Label l3;public void init() l1 = new Label(); l2 = new Label(标签对象2); l3 = new Label(标签对象3,Label.CENTER); this.add(l1); this.add(l2); this.add(l3);public void start()Java实用教程l1.set

203、Text(标签对象1);str1 = l2.getText();i1 = l3.getAlignment();repaint(); public void paint(Graphics g) g.drawString(获取第二个对象的文本: + str1,40,60);g.drawString(标签对象3的对齐方式为: + i1,40,80); ;Java实用教程图6.5 Label对象的界面Java实用教程6.1.5 列表列表 List展示给用户一个滚动的文本项列表。用户可以选择其中一项或多项。它的构造函数和其它常用方法如下: public List() 构建一个新的空滚动列表。 publi

204、c List(int rows) 构建一个新的rows可见行的滚动列表。 public List(int rows, boolean multipleMode) 构建一个新的rows可见行的滚动列表,并设置是否可以多项选择。multipleMode为true时,允许用户多项选择。Java实用教程public void add(String item) 在滚动列表最后添加新的一项item。 public void add(String item, int index) 在index位置添加item项。public String getItem(int index) 返回index位置的项。pub

205、lic int getItemCount() 返回列表中项的数目。public String getItems() 返回列表中的项,为一个字符串数组。Java实用教程public int getSelectedIndex() 返回列表中选中项的索引。public String getSelectedItem() 返回列表中选中的项。public boolean isIndexSelected(int index) 判断index项是否选中。public void remove(int position) 删除position项。public void remove(String item) 删

206、除item项。Java实用教程public void removeAll() 删除列表中所有元素。public void replaceItem(String newValue, int index) 将index位置的项替换为newValue。 public void select(int index) 选中index位置的项,通常用于初始化。Java实用教程【例6.5】测试List类,用户界面如图6.6所示。源程序代码如下:/程序文件名UseList.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;p

207、ublic class UseList extends AppletString str1 = new String();String str2 = new String();int i1 = 0;int i2 = 0;Java实用教程List l1,l2,l3;/声明对象public void init() l1 = new List(); l2 = new List(5); l3 = new List(5,true); /列表添加内容 l1.add(苹果); l1.add(香蕉); l1.add(梨); l2.add(语文); l2.add(数学);Java实用教程l2.add(英语);

208、l2.add(化学); l3.add(钢笔); l3.add(铅笔); l1.select(1); l3.select(1); this.add(l1); this.add(l2); this.add(l3);public void start()Java实用教程str1 = l1.getItem(2);i1 = l1.getItemCount();l2.replaceItem(英语,2);str2 = l3.getSelectedItem();repaint(); public void paint(Graphics g) g.drawString(第一个对象的索引为2的元素: + str1

209、,40,100);g.drawString(第一个对象的元素个数: + i1,40,120);g.drawString(第三个对象选中的元素为: + str2,40,140); ;Java实用教程图6.6 List对象的界面Java实用教程6.1.6 滚动条滚动条 Scrollbar给用户提供一个组件,方便用户在一系列范围的值中进行选择。它的常用属性如表6.2所示。表表6.2 Scrollbar类的常用属性及缺省值类的常用属性及缺省值Java实用教程它的构造函数和其它常用方法如下:public Scrollbar() 构建一个新的垂直滚动条。public Scrollbar(int orien

210、tation) 构建一个指定方向的滚动条。Orientation的值为HORIZONTAL(0)表示水平滚动条,值为VERTICAL(1)表示垂直滚动条。public Scrollbar(int orientation, int value, int visible, int minimum, int maximum) 构建一个指定方向、初始值、可见性、最小值和最大值的滚动条。Java实用教程public int getValue() 返回滚动条的当前值。 public int getMinimum()返回最小值。public int getMaximum()返回最大值。Java实用教程【例6

211、.6】测试Scrollbar类,用户界面如图6.7所示。源程序代码如下:/程序文件名UseScrollbar.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UseScrollbar extends Appletint i1 = 0;int i2 = 0;int i3 = 0;int i4 = 0;int i5 = 0;Scrollbar s1;/声明对象Java实用教程Scrollbar s2;Scrollbar s3;public void init() s1 = new S

212、crollbar(); s2 = new Scrollbar(Scrollbar.HORIZONTAL); s3 = new Scrollbar(Scrollbar.VERTICAL,50,0,10,500); this.add(s1); this.add(s2); this.add(s3);public void start()Java实用教程i1 = s1.getOrientation();i2 = s2.getOrientation();i3 = s3.getValue();i4 = s3.getMinimum();i5 = s3.getMaximum();repaint();publi

213、c void paint(Graphics g)g.drawString(第一个对象的方向: + i1,40,80);Java实用教程g.drawString(第二个对象的方向: + i2,40,100);g.drawString(第三个对象的滑块值: + i3,40,120);g.drawString(第三个对象的最小值: + i4,40,140);g.drawString(第三个对象的最大值: + i5,40,160); ;Java实用教程图6.7 Scrollbar对象的测试界面Java实用教程6.1.7 文本框文本框TextField对象用作单行文本的编辑。它的构造函数和其它常用方法如

214、下:public TextField() 构建一个空的文本框。public TextField(int columns) 构建一个文本框,columns给出文本框的宽度。public TextField(String text) 构建一个文本框,用text给出初始化内容。public TextField(String text, int columns) Java实用教程 构建一个文本框,text给出初始化的内容,columns给出文本框的宽度。 public void setText(String t) 将文本框的内容设置为特定文本t。 public String getText() 返回文

215、本框的内容,返回值为字符串。 public void setEditable(boolean b) 设定文本框内容是否是用户可编辑的,b为false时,表示不可编辑,b为true时,表示可编辑。通常创建一个文本框时默认为用户可编辑的。 public int getColumns() 获取列数。Java实用教程 【例6.7】TextField类的测试,用户界面如图6.8所示。源程序代码如下:/程序文件名UseTextField.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class Use

216、TextField extends AppletString str1 = new String();int i1 = 0;int i2 = 0; TextField tf1, tf2, tf3, tf4;public void init()Java实用教程tf1 = new TextField(); tf2 = new TextField(20); tf3 = new TextField(文本对象3); tf4 = new TextField(文本对象4, 30); add(tf1); add(tf2); add(tf3); add(tf4);public void start()Java实

217、用教程tf1.setText(文本对象1);tf2.setText(文本对象2);str1 = tf3.getText();i1 = tf3.getColumns();i2 = tf4.getColumns();tf4.setEditable(false);repaint(); public void paint(Graphics g) g.drawString(第三个对象的文本内容为: + str1,20,140);g.drawString(第三个对象的列数为: + i1,20,160);g.drawString(第四个对象的列数为: + i2,20,180); ;Java实用教程图6.8

218、TextField对象的界面Java实用教程6.1.8 文本区域文本区域 TextArea对象用于允许多行编辑的文本区域,可以设置为可编辑的,也可以设为只读属性。 public TextArea() 构建一个空文本区域。 public TextArea(int rows, int columns) 构建一个行数为rows、列数为columns的空文本区域。 public TextArea(String text) 构建一个文本为text的文本区域。 Java实用教程 public TextArea(String text, int rows, int columns) 构建一个文本为text、

219、行数为rows、列数为columns的文本区域。 public TextArea(String text, int rows, int columns, int scrollbars) 构建一个文本为text、行数为rows、列数为columns的文本区域。滚动条的情况由scrollbars参数决定。Scrollbars的取值如表6.3所示。 Java实用教程表表6.3 TextArea中的滚动条属性值中的滚动条属性值Java实用教程 public void append(String str) 将非空str字符串文本添加到文本区域中。 public void insert(String st

220、r, int pos) 在指定位置pos插入非空字符串str。 public void replaceRange(String str, int start, int end) 将start开始位置到end结束位置的字符串替换成非空字符串str,其中start位置的字符被替换,end位置的字符仍保留。 public void setText(String t) 将文本框的内容设置为特定文本t。Java实用教程 public String getText() 返回文本框的内容,返回值为字符串。 public void setEditable(boolean b) 设定文本框内容是否是用户可编辑的

221、。b为false时,表示不可编辑。b为true时,表示可编辑。通常创建一个文本框时,默认为用户可编辑的。 public int getColumns() 返回列数。 public int getRows() 返回行数。Java实用教程 【例6.8】测试TextArea类,用户界面如图6.9所示。源程序代码如下:/程序文件名UseTextArea.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UseTextArea extends AppletString str1 = new

222、String();String str2 = new String();int i1,i2,i3;TextArea t1,t2,t3,t4,t5;/声明对象Java实用教程public void init() t1 = new TextArea(); t2 = new TextArea(2,20); t3 = new TextArea(文本区域对象3); t4 = new TextArea(文本区域对象4, 3, 10); t5 = new TextArea(文本区域对象5, 2, 24, TextArea.SCROLLBARS_BOTH); this.add(t1); this.add(t2

223、); this.add(t3); this.add(t4); this.add(t5);Java实用教程public void start()t1.setText(文本区域对象1);t2.append(文本区域对象2);t3.insert(插入3,4);str1 = t3.getText();t4.replaceRange(替换,2,6);str2 = t4.getText();i1 = t4.getRows();i2 = t5.getColumns();i3 = t5.getScrollbarVisibility();t5.setEditable(false);repaint();Java实

224、用教程public void paint(Graphics g)g.drawString(第三个对象的文本内容为: + str1,40,400);g.drawString(第四个对象的文本内容为: + str2,40,420);g.drawString(第四个对象的行数为: + i1,40,440);g.drawString(第五个对象的列数为: + i2,40,460);g.drawString(第五个对象的滚动条情况为: + i3,40,480); ;Java实用教程图6.9 TextArea对象的界面Java实用教程6.2 布布 局局6.2.1 流式布局器流式布局器 流式布局将组件按照从

225、左到右的顺序自然排列,是缺省的设置方式。其构造函数如下: FlowLayout() 构建一个新的流式布局器,中央对齐,对象之间以5单元水平和垂直间隔。 FlowLayout(int align) 构建一个新的流式布局器,通过align设置对齐方式,对象之间以5单元水平和垂直间隔。 FlowLayout(int align, int hgap, int vgap) 构建一个新的流式布局器,通过align设置对齐方式,对象之间以hgap单元水平间隔并以vgap单元垂直间隔。Java实用教程6.2.2 边缘布局器边缘布局器 边缘布局器是一个分为北(NORTH)、南(SOUTH)、东(EAST)、西(

226、WEST)和中央(CENTER)五部分的容器。其构造函数如下: BorderLayout() 构建一个新的边缘布局,对象之间没有间隔。 BorderLayout(int hgap, int vgap) 构建一个新的边缘布局,对象之间的水平间隔为hgap,垂直间隔为vgap。Java实用教程6.2.3 面板面板 面板是最简单的容器类,应用程序可以在面板提供的空间里放置任意组件及其它的面板。 Panel() 使用缺省的布局管理器创建一个新的面板。缺省的布局管理器为流式管理器。 Panel(LayoutManager layout) 用指定的layout布局管理器创建一个面板。 public voi

227、d setLayout(LayoutManager mgr) 设置布局管理器。 Java实用教程 【例6.9】下面是一个综合性实例,采用本章介绍的界面对象设置用户界面并进行布局管理。经过布局后的界面如图6.10所示。/程序文件名UsePanel.javaimport java.awt.*;import java.applet.*;import java.applet.Applet;public class UsePanel extends AppletLabel lblName,lblNumber,lblSex,lblJob,lblText;TextField tfName,tfNumber;

228、Checkbox chMale, chFemale;Java实用教程CheckboxGroup c; TextArea taText;Choice chJob;Button btnOk,btnCancel;Panel p1,p2,p3,p4,p5,p6,p7,p8,p9;public void init()lblName = new Label(姓名:);lblNumber = new Label(身份证号:);lblSex = new Label(性别);lblJob = new Label(职业);lblText = new Label(个性化宣言:);Java实用教程tfName = n

229、ew TextField(23);tfNumber = new TextField(20);taText = new TextArea(10,20);c = new CheckboxGroup();chMale = new Checkbox(男,c,true);chFemale = new Checkbox(女,c,false);chJob = new Choice();chJob.add(计算机业);chJob.add(医生);chJob.add(教师);chJob.add(军队);btnOk = new Button(确定);btnCancel = new Button(取消);Java实

230、用教程p1 = new Panel();p2 = new Panel();p3 = new Panel();p4 = new Panel();p5 = new Panel();p6 = new Panel();p7 = new Panel(new BorderLayout();p8 = new Panel();p9 = new Panel(new BorderLayout();p1.add(lblName);p1.add(tfName);p2.add(lblNumber);p2.add(tfNumber);p3.add(lblSex);Java实用教程p3.add(chMale);p3.add

231、(chFemale);p4.add(lblJob);p4.add(chJob);p5.add(p3);p5.add(p4);p6.setLayout(new BorderLayout();p6.add(p1,BorderLayout.NORTH);p6.add(p2,BorderLayout.CENTER);p6.add(p5,BorderLayout.SOUTH);p7.add(lblText,BorderLayout.NORTH);p7.add(taText,BorderLayout.CENTER);Java实用教程p8.setLayout(new FlowLayout(FlowLayou

232、t.CENTER,30,10);p8.add(btnOk);p8.add(btnCancel);p9.add(p6,BorderLayout.NORTH);p9.add(p7,BorderLayout.CENTER);p9.add(p8,BorderLayout.SOUTH);add(p9); ;Java实用教程图6.10 经过布局后的界面Java实用教程6.3 java.swing包包6.3.1 基本组件基本组件JButton为轻量级按钮组件,对应着Button组件类。JLabel为轻量级标签组件,对应着Label组件类。JCheckBox为轻量级复选框,对应CheckBox类。Jradio

233、Button为轻量级单选按钮,需要添加在ButtonGroup组中。JRadioButton jMale = new JRadioButton(男);JRadioButton jFemale = new JRadioButton(女);Java实用教程 ButtonGroup group = new ButtonGroup(); group.add(jMale); group.add(jFemale); JComoBox对应Choice组件,但添加项的方法不同,使用的是addItem方法,例如: JComboBox cmbJob = new JComboBox(); cmbJob.addIte

234、m(计算机业); cmbJob.addItem(医生); cmbJob.addItem(教师);Java实用教程 cmbJob.addItem(军队); JTextField组件为允许对单行文本进行编辑的轻量级组件,对应TextField类。 JTextArea组件用于在多行区域中显示纯文本并进行编辑。 Jpanel为轻量级面板控件,对应原来的Panel类。 JApplet类继承自Applet类。Java实用教程6.3.2 JTable JTable是用于显示和编辑的两维表单元。它的构造函数和常用方法为: public JTable() 构造一个空的JTable对象。 public void

235、setModel(TableModel dataModel) 为表对象设置数据模型dataModel,并将新数据模型进行注册。 DefaultTableModel是一个实现模型,使用一系列Vector对象实现表单元数据的填充。它的构造函数和常用方法为: public DefaultTableModel() 构造函数。Java实用教程 public void addColumn(Object columnName) 添加一列标题。 public void addRow(Vector rowData) 在模型对象的末尾添加一行Vector对象的数据。 构造Jtable对象的步骤如下: (1) 构造

236、一个空JTable对象。 JTable tblInf = new JTable(); (2) 构造DefaultTableModel对象,用setModel方法将此对象绑定到JTable上。 DefaultTableModel dtm = new DefaultTableModel();Java实用教程 (3) 具体实现DefaultTableModel对象(addColomn方法实现列标题设置,addRow方法实现数据行添加)。 初始化Vector列表,添加列标题。 Vector vCdata = new Vector(); vCdata.add(姓名); vCdata.add(身份证号);

237、 vCdata.add(性别); tblInf.setModel(dtm); for (int i=0; ivCdata.size(); i+) dtm.addColumn(String)vCdata.elementAt(i);Java实用教程 初始化Vector列表,添加行数据。 Vector vRdata = new Vector(); vRdata.add(王飞); vRdata.add(111122197904290902); vRdata.add(男); dtm.addRow(vRdata); JTable没有内嵌滚动功能,将之放入JScrollPane对象中并进行显示。 JScro

238、llPane s = new JScrollPane(tblInf); getContentPane().add(s,BorderLayout.CENTER);Java实用教程6.3.3 Jtree JTree控件用于显示一系列分层数据,即树状显示。它的构造函数和常用方法为: public void setModel(TreeModel newModel) 设置提供数据的TreeModel模型。TreeModel是一个接口,接口内实现的类为DefaultTreeModel类,DefaultTreeModel是一个使用TreeNodes的简单树数据模型,下面给出它的构造函数。 public De

239、faultTreeModel(TreeNode root) Java实用教程 创建根结点为root的树,其中每个结点都可以有子结点。TreeNode是一个接口,它包含一个DefaultTreeNode类,DefaultTreeNode类表达了一个树型数据结构中具有一般意义的结点。每个树结点至多有一个父结点,0个或多个子结点。其构造函数为: public DefaultMutableTreeNode(Object userObject) 创建一个无父结点、无子结点的树结点。例如 public DefaultMutableTreeNode f = new DefaultMutableTreeNod

240、e(个人信息); public add(MutableTreeNode newChild) 将newChild结点添加到树结点的末尾,使之称为当前结点的子结点。Java实用教程 创建树结构的步骤如下: (1) 构建JTree对象。 JTree tree = new JTree(); (2) 构造DefaultMutableTreeModel对象,使用SetModel方法将DefaultMutableTreeModel对象绑定到Jtree对象。 tree.setModel(new DefaultTreeModel(root);Java实用教程(3) 构造树。 构造根结点。 DefaultMuta

241、bleTreeNode root; 构造分支结点,添加到根结点。 DefaultMutableTreeNode NodeName, NodeNumber, NodeSex; NodeName = new DefaultMutableTreeNode(姓名); NodeNumber = new DefaultMutableTreeNode(身份证号); NodeSex = new DefaultMutableTreeNode(性别); root.add(NodeName); root.add(NodeNumber); root.add(NodeSex); Java实用教程 添加叶子结点并添加到分

242、支结点。 leafName = new DefaultMutableTreeNode(王飞); leafNumber = new DefaultMutableTreeNode(111122197904290902); leafSex = new DefaultMutableTreeNode(男); NodeName.add(leafName); NodeNumber.add(leafNumber); NodeSex.add(leafSex);Java实用教程 使用DefaultMutableTreeModel的构造函数,将根结点作为参数构造树结构中的数据。 DefaultTreeModel d

243、Tree = new DefaultTreeModel(root); JTree没有内嵌的滚动属性,较大的树状结构可以显示在JScrollPane上。JScrollPane scroll = new JScrollPane(tree);getContentPane().add(scroll);Java实用教程6.3.4 实例实例 【例6.10】 测试java.swing包提供的轻量级组件的例子,主类TestSwing扩展于JFrame类,显示结果如图6.11所示。界面分为三部分,上一部分和上例中的显示结果一一对应,中间一部分为table表记录,下面的部分为树状显示结构。源程序代码如下:/文件名

244、为:TestSwing.javaimport java.awt.*;import java.util.*;import javax.swing.*;import javax.swing.tree.*;import javax.swing.table.*;Java实用教程import javax.swing.ButtonGroup;public class TestSwing extends JFrameJLabel lblName = new JLabel(姓名:);JLabel lblNumber = new JLabel(身份证号);JLabel lblSex = new JLabel(性

245、别);JLabel lblJob = new JLabel(职业);JLabel lblText = new JLabel(个性化宣言);JTextField tfName = new JTextField(23);JTextField tfNumber = new JTextField(20);JTextArea taText = new JTextArea(5,20);JRadioButton jMale = new JRadioButton(男);Java实用教程JRadioButton jFemale = new JRadioButton(女);ButtonGroup group =

246、new ButtonGroup();JComboBox cmbJob = new JComboBox();JButton btnOk = new JButton(确定);JButton btnDisplay = new JButton(取消);JTable tblInf = new JTable();DefaultTableModel dtm = new DefaultTableModel();/布局设置JTree tree = new JTree();JPanel p1 = new JPanel();JPanel p2 = new JPanel();Java实用教程JPanel p3 = n

247、ew JPanel();JPanel p4 = new JPanel();JPanel p5 = new JPanel();JPanel p6 = new JPanel();JPanel p7 = new JPanel(new BorderLayout();JPanel p8 = new JPanel();JPanel p9 = new JPanel(new BorderLayout();public TestSwing()group.add(jMale);group.add(jFemale);Java实用教程cmbJob.addItem(计算机业);cmbJob.addItem(医生);cm

248、bJob.addItem(教师);cmbJob.addItem(军队);p1.add(lblName);p1.add(tfName);p2.add(lblNumber);p2.add(tfNumber);p3.add(lblSex);p3.add(jMale);p3.add(jFemale);p4.add(lblJob);p4.add(cmbJob);Java实用教程p5.add(p3);p5.add(p4);p6.setLayout(new BorderLayout();p6.add(p1,BorderLayout.NORTH);p6.add(p2,BorderLayout.CENTER);

249、p6.add(p5,BorderLayout.SOUTH);p7.add(lblText,BorderLayout.NORTH);p7.add(taText,BorderLayout.CENTER);p8.setLayout(new FlowLayout(FlowLayout.CENTER,30,10);p8.add(btnOk);p8.add(btnDisplay);p9.add(p6,BorderLayout.NORTH);p9.add(p7,BorderLayout.CENTER);Java实用教程 p9.add(p8,BorderLayout.SOUTH); /调用设置表的方法 set

250、Table(); /调用设置树的方法 setTree();getContentPane().add(p9,BorderLayout.NORTH);JScrollPane s = new JScrollPane(tblInf);getContentPane().add(s,BorderLayout.CENTER);getContentPane().add(tree,BorderLayout.SOUTH);/设置表,用Vector辅助添加public void setTable()Java实用教程Vector vCdata = new Vector();vCdata.add(姓名);vCdata.

251、add(身份证号);vCdata.add(性别);tblInf.setModel(dtm);for (int i=0; ivCdata.size(); i+)dtm.addColumn(String)vCdata.elementAt(i);Vector vRdata = new Vector();vRdata.add(王飞);vRdata.add(111122197904290902);vRdata.add(男);dtm.addRow(vRdata);Java实用教程/设置树public void setTree() DefaultMutableTreeNode root; DefaultMu

252、tableTreeNode NodeName, NodeNumber, NodeSex; DefaultMutableTreeNode leafName, leafNumber, leafSex; root = new DefaultMutableTreeNode(个人信息); NodeName = new DefaultMutableTreeNode(姓名); leafName = new DefaultMutableTreeNode(王飞); NodeNumber = new DefaultMutableTreeNode(身份证号); leafNumber = new DefaultMut

253、ableTreeNode(111122197904290902);Java实用教程NodeSex = new DefaultMutableTreeNode(性别);leafSex = new DefaultMutableTreeNode(男);root.add(NodeName);root.add(NodeNumber);root.add(NodeSex);NodeName.add(leafName);NodeNumber.add(leafNumber);NodeSex.add(leafSex);/设置Tree渲染的基本属性tree.getSelectionModel().setSelecti

254、onMode( TreeSelectionModel.SINGLE_TREE_SELECTION );Java实用教程 tree.setShowsRootHandles( true ); /树不可以编辑tree.setEditable( false ); tree.setModel(new DefaultTreeModel(root);public static void main(String args) TestSwing ts = new TestSwing();ts.setSize(400,450);ts.show(); Java实用教程图6.11 显示结果Java实用教程习习 题题

255、1. 设计一个界面,如图6.12所示。其中身份证一栏有四项,分别为身份证、军人证、学生证和护照。图图6.12Java实用教程 2. 设计一个标签区域和三个滚动条,滚动条的取值范围均为0255,即使得滚动条的取值对应颜色对象的红、绿、蓝三个基色的值,初始标签颜色为红色。 3. 用java.swing包中的类设计如图6.12所示的界面,然后进行详细的布局设计。 4. 图6.13中的Xuesheng表,代表了每个学生的基本信息,在Applet界面上设计此表,并依次进行记录的添加。Java实用教程图6.13 Xuesheng表的记录显示Java实用教程 5. 用树状结构显示如图6.14所示的部分文件系

256、统目录,要求节点的名字为文件夹的名字或者文件的名字,图片无需显示。注意ppt文件夹下含有两个文件,分别为6_10.ppt和6_10.vsd。图6.14 部分文件系统目录Java实用教程第7章 异常、事件和多线程机制 7.1 异常异常 7.2 事件事件 7.3 多线程机制多线程机制 习习 题题 Java实用教程7.1 异异 常常7.1.1 定义定义 异常是指当程序中某些地方出错时创建的一种特殊的运行时错误对象。Java创建异常对象后,就发送给Java程序,即抛出异常(throwing an exception)。程序捕捉到这个异常后,可以编写相应的异常处理代码进行处理。使用异常处理可以使得程序更

257、加健壮,有助于调试和后期维护。Java实用教程7.1.2 异常类异常类 由继承类图可以看出,Throwable类派生了两个类:Exception类和Error类,其中Error类系统保留,而Exception类供应用程序使用,它下面又派生出几个具体的异常类,都对应着一项具体的运行错误,如图7.1所示。Java实用教程图7.1 异常类图Java实用教程Exception类中常用的方法为:public String toString() 返回异常的简短描述。public String getMessage() 返回异常的详细信息描述。异常类分为系统定义的异常和用户自定义的异常。Java实用教程 1

258、. 系统定义的异常系统定义的异常 图7.1中Exception派生的这些子类都是系统事先定义好并包含在Java类库中的,系统定义的异常对应着一些系统错误,如中断、文件没找到等错误。表7.1列举了一些常见的系统异常类。表表7.1 常见的系统异常类常见的系统异常类Java实用教程 2. 用户自定义异常用户自定义异常 用户自定义异常用来处理用户应用程序中的特定逻辑的运行错误,用户自定义的异常类通常继承自Exception类,例如:public class UserDefineException extends Exceptionpublic UserDefineException(String ms

259、g)super(msg);Java实用教程7.1.3 异常处理异常处理 Java异常通常在调用某些方法不一定完全成功时抛出,针对抛出的异常程序需要给出相应的处理,这称为异常处理。异常处理分为三个部分:捕捉异常、程序流程的跳转和异常处理语句块。 当一个异常被抛出时,程序中有专门的语句来接收这个被抛出的异常对象,这个过程就是捕捉异常;当一个异常类的对象被捕捉或接收后,用户程序就会发生流程跳转,系统中止程序运行,跳转到异常处理语句的执行,或者直接跳出系统,回到操作系统状态下。在Java语言中,try语句用来启动Java的异常处理机制,通常是可能抛出异常的语句的调用;而catch语句进行捕捉和处理异常

260、,有时添加finally语句块,finally中的语句是正常执行或者处理异常之后必须执行的语句。语句格式如下:Java实用教程try语句块;catch(异常类 异常类参数名)异常处理语句块;finally try或者catch语句完毕后必须执行的语句(通常用于关闭文件流对象或者数据库对象等); Java实用教程1. 直接抛出异常直接抛出异常例如:public void myMethod()tryurlName = new URL(http:/);getAppletContext().showDocument(urlName,right);catch(MalformedURLException

261、e)System.out.println(e.getMessage();Java实用教程 try部分试图打开一个网址http:/,如果不成功,比如网址输入错误,那么引发异常程序忽略try中的下一行代码,直接跳到catch块中执行语句System.out.println(e.getMessage(),打印出引发的异常的错误信息描述。其中MalformedURLException说明引发的异常可能是URL网址输入错误类。Java实用教程 2. 间接抛出异常间接抛出异常 例如:public void myMethod() throws MalformedURLExceptionurlName = n

262、ew URL(http:/);getAppletContext().showDocument(urlName,right);在方法后面直接抛出。Java实用教程3. 综合方法综合方法例如:public void myMethod() throws MalformedURLException tryurlName = new URL(http:/);getAppletContext().showDocument(urlName,right);catch(MalformedURLException e)System.out.println(e.getMessage();Java实用教程7.1.4

263、多异常的处理多异常的处理 多异常的处理使用多个catch来捕捉不同类的异常,Java中对catch块的数量没有限制。格式如下:Try.catch(异常类1 标识符)Java实用教程.catch(异常类2 标识符).finally.Java实用教程【例7.1】 测试多异常处理和自定义异常。源程序代码如下:/程序文件名UseMultiException.javapublic class UseMultiException extends Exceptionstatic String str1;static String str2;public static void main(String arg

264、s)int i1 = 0;int i2 = 0;str1 = new String(args0);str2 = new String(args1);String strResult = new String();tryJava实用教程read(str1, str2);i1 = Integer.parseInt(str1);i2 = Integer.parseInt(str2);int result = i1/i2;strResult = String.valueOf(result);catch(NumberFormatException e)strResult = 错误的数字: + e.get

265、Message();catch(ArithmeticException e)strResult = 被0除错误: + e.getMessage();Java实用教程str1 = s1.trim();str2 = s2.trim();if (str1.equals(0) throw (new UserDefineException(本系统0不能为被除数); ;class UserDefineException extends Exceptionpublic UserDefineException(String msg)super(msg);Java实用教程具体运行测试如下,结果如图7.2所示。j

266、ava UseMultiException 2gf 5数字格式出错。java UseMultiException 2gf 0数字格式出错,下面的程序代码不再执行,无法抛出第二个异常。java UseMultiException 2 0被0除出错。java UseMultiException 0 3引发用户自定义错误。java UseMultiException 9 3 9/3的答案为3。Java实用教程图7.2 异常测试输出Java实用教程7.2 事事 件件 事件用于描述程序、系统和程序使用者之间的各种活动。这些事件由系统事先定义好,当用户在图形界面上单击控件或双击鼠标时就可能引发某个事件,而

267、用户程序中需要编制相应的代码来对这些事件做出处理。 1. 事件源事件源 图形用户界面上每个可能产生事件的组件称为事件源。Java实用教程 2. 事件监听者事件监听者 Java系统中注册的用于接收特殊事件的类。不同的事件对应着不同的监听者,要想事件被监听者监听并处理,则需先将事件源注册到监听者。 3. 事件处理流程事件处理流程 事件源触发事件并将事件作为一个参数传递给监听者,监听者实现某个接口中的抽象方法,从而实现对事件的处理。 Java的事件处理机制是一个委托事件模型,如图7.3所示。Java实用教程图7.3 Java事件处理机制Java实用教程 事件源注册的方法如下: public void

268、 addActionListener(ActionListener l) 添加特定的动作,监听接收来自事件源的动作事件,如果l为空,不会产生任何动作。 监听者实现的接口为ActionListener接口,接口ActionListener来自包java.awt.event。在此接口中只有一个方法: public void actionPerformed(ActionEvent e) 当事件对象e发生时,调用此方法。监听者就需要实现这个方法。 Java中常用的事件和相应的事件监听者如表7.2所示。Java实用教程表表7.2 常用事件及其监听者常用事件及其监听者Java实用教程7.2.1 动作事件动

269、作事件(ActionEvent) ActionEvent包含一个事件,该事件为执行动作事件ACTION_PERFORMED。触发这个事件的动作为:(1) 点击按钮。(2) 双击列表中的选项。(3) 选择菜单项。(4) 在文本框中输入回车。Java实用教程 常用方法如下: public String getActionCommand() 返回引发某个事件的命令按钮的名字,如果名字为空,那么返回标签值。 public void setActionCommand(String command) 设置引发事件的按钮的名字,默认设置为按钮的标签。Java实用教程【例7.2】测试动作事件。源程序代码如下:

270、/程序文件名UseButton.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.applet.Applet;public class UseButton extends Applet implements ActionListenerString str1 = new String();Button b1; /声明按钮对象;Button b2;Color c;public void init()Java实用教程 b1 = new Button(); b2 = new Button(按钮

271、对象2); /添加事件监听者 b1.addActionListener(this); b2.addActionListener(this); this.add(b1); this.add(b2);public void start()b1.setLabel(按钮对象1);str1 = b2.getLabel();repaint();Java实用教程public void paint(Graphics g)g.setColor(c);g.drawString(引发事件的对象的标签: + str1, 40,60);/实现接口中的方法,响应动作事件public void actionPerforme

272、d(ActionEvent e)String arg = e.getActionCommand();if(arg = 按钮对象1)c = Color.red;str1 = 按钮对象1;Java实用教程else if(arg = 按钮对象2)c = Color.blue;str1 = 按钮对象2;repaint(); Java实用教程 单击“按钮对象1”,引发对象1的单击事件,输出结果如图7.4所示;单击“按钮对象2”,引发对象2的单击事件,输出结果如图7.5所示。图7.4 单击“按钮对象1”的输出Java实用教程图7.5 单击“按钮对象2”的输出Java实用教程7.2.2 文本事件文本事件(T

273、extEvent) 文本事件即代表文本区域中文本变化的事件TEXT_VALUE_CHANGED,在文本区域中改变文本内容。 public void addTextListener(TextListener l) 添加特定的文本事件,监听者接收来自文本对象的文本事件。如果l为空,那么不会抛出任何异常,而且也不会完成任何动作。 public interface TextListener extends EventListener 用于接收文本事件的监听者接口。当对象的文本发生变化时,调用监听者对象的方法。Java实用教程接口中的方法为:public void textValueChanged(Te

274、xtEvent e) 当文本发生改变时调用。public Object getSource()发生事件的对象,从EventObject继承来的方法。Java实用教程【例7.3】测试文本事件。源程序代码如下:/程序文件名UseTextEvent.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.applet.Applet; public class UseTextEvent extends Applet implements ActionListener, TextListener Tex

275、tField tOld;TextArea tNew;Panel p;public void init()Java实用教程 tOld = new TextField(25); tNew = new TextArea(8,25); /添加事件监听者 tOld.addActionListener(this); tOld.addTextListener(this); /设置界面 p = new Panel(new BorderLayout(); p.add(tOld,BorderLayout.NORTH); p.add(tNew,BorderLayout.SOUTH); add(p);Java实用教程

276、/响应文本事件public void textValueChanged(TextEvent e)if(e.getSource() = tOld)tNew.setText(tOld.getText();/响应动作事件public void actionPerformed(ActionEvent e)if(e.getSource() = tOld)tNew.setText();Java实用教程 在文本框中键入“你好,这是文本事件同步”字符串,可以看见文本区域中的字符跟随变化,如图7.6所示,这是响应文本事件。键入字符串后按回车键,则发生响应动作事件,将文本区域清空,如图7.7所示。 图7.6 响应

277、文本事件 Java实用教程图7.7 响应动作事件Java实用教程7.2.3 选择事件选择事件(ItemEvent) 选择事件中包含以事件为代表的选择项,选中状态发生变化的事件ITEM_STATE_ CHANGED。引发的动作为:(1) 改变列表类改变列表类List对象选项的选中或不选中状态。对象选项的选中或不选中状态。(2) 改变下拉列表类改变下拉列表类Choice对象选项的选中或不选中状态。对象选项的选中或不选中状态。(3) 改变复选按钮类改变复选按钮类Checkbox对象的选中或不选中状态。对象的选中或不选中状态。Java实用教程事件源对象注册的方法如下:public void addIt

278、emListener(ItemListener l) 添加特定的项监听者,接收对象的选择项发生变化的事件。public ItemSelectable getItemSelectable() ItemEvent事件的方法,返回产生事件的事件源对象。public interface ItemListener extends EventListener接收选项事件的监听者接口。当选项中事件发生时,调用监听对象的itemStateChanged方法。public void itemStateChanged(ItemEvent e)当用户选中一项或未选中一项时,调用这个方法。Java实用教程 【例7.4

279、】测试选择事件。分别对设置颜色的复选框和有三种字号10、12和14的组合框进行选择时,标签的颜色和字体发生变化。源程序代码如下:/程序文件名UseItemEvent.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.applet.Applet;public class UseItemEvent extends Applet implements ItemListenerJava实用教程Checkbox cDisp;Button btnDisp;Choice cFont;public vo

280、id init() cDisp = new Checkbox(红色); btnDisp = new Button(颜色显示); cFont = new Choice(); cFont.add(10); cFont.add(12); cFont.add(14); /添加事件 cDisp.addItemListener(this);Java实用教程 cFont.addItemListener(this); add(cDisp); add(cFont); add(btnDisp);/接口事件public void itemStateChanged(ItemEvent e)Checkbox temp;

281、Choice temp2;Font oldF;/复选框if(e.getItemSelectable() instanceof Checkbox)Java实用教程temp = (Checkbox)(e.getItemSelectable();/选中为红色,否则为蓝色if(temp.getState()btnDisp.setBackground(Color.red);elsebtnDisp.setBackground(Color.blue);/组合框if(e.getItemSelectable() instanceof Choice)oldF = btnDisp.getFont();Java实用教

282、程temp2 = (Choice)(e.getItemSelectable();String s = temp2.getSelectedItem();/设置字体btnDisp.setFont(new Font(oldF.getName(),oldF.getStyle(),Integer.parseInt(s); Java实用教程 当选中红色复选框和组合框中的字号为14时,显示界面如图7.8所示;当未选中红色复选框和选中组合框中的字号为10时,显示界面如图7.9所示。图7.8 选中红色和字号为14的界面 Java实用教程图7.9 未选中红色和字号为10的界面Java实用教程7.2.4 调整事件调

283、整事件(AdjustmentEvent) 调整事件包含一个事件,即ADJUSTMENT_VALUE_CHANGED事件,当操纵滚动条改变其滑块位置时引发动作。AjustEvent的方法如下: public Adjustable getAdjustable() 返回引发事件的对象。 public int getValue() 返回调整事件中的当前值。Java实用教程public void addAdjustmentListener(AdjustmentListener l) 添加调整监听者来接收来自对象的AdjustmentEvent实例。public interface AdjustmentL

284、istener extends EventListener接收调整事件的监听接口,有一个方法:public void adjustmentValueChanged(AdjustmentEvent e) 可在调整改变时调用这个值。Java实用教程 【例7.5】测试调整事件。设置一个水平滚动条,取值为136,随着滑块的变化,滚动条的值将显示在文本区域中,并且字体大小也会跟随变化。源程序代码如下:/程序文件名UseAdjustmentEvent.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java

285、.applet.Applet;public class UseAdjustmentEvent extends Applet implements AdjustmentListenerJava实用教程Scrollbar s;TextArea txtValue;Panel p;public void init() s = new Scrollbar(Scrollbar.HORIZONTAL,0,1,10,36); /添加监听者 s.addAdjustmentListener(this); txtValue = new TextArea(5,25); /界面布局 p = new Panel(new

286、BorderLayout(); p.add(s,BorderLayout.NORTH);Java实用教程 p.add(txtValue,BorderLayout.SOUTH); add(p);public void start()public void adjustmentValueChanged(AdjustmentEvent e)int value;Font oldF;if(e.getAdjustable() = s) /得到滚动条的值Java实用教程value = e.getValue();/将值写入文本区域txtValue.setText(new Integer(value).toSt

287、ring();/按照滚动条的值设置字体oldF = txtValue.getFont();txtValue.setFont(new Font(oldF.getName(),oldF.getStyle(),value); Java实用教程 随着滚动条的变化,可以看见文本区域中的取值以及大小都会跟随变化,取值为10和取值为35时的效果各不相同,如图7.10和图7.11所示。图7.10 字号为10的界面 Java实用教程图7.11 字号为35的界面Java实用教程7.2.5 鼠标事件鼠标事件(MouseEvent) 表明画布或界面组件中发生的鼠标事件,包含按下鼠标、释放鼠标、单击鼠标、进入部件的地理

288、位置的鼠标事件和退出部件的地理位置的鼠标事件,以及鼠标移动事件(鼠标移动和鼠标拖动)。 鼠标使用addMouseListener方法注册,通过MouseListener接收鼠标事件;鼠标还可以使用addMouseMotionListener方法注册,通过MouseMotionListener监听者监听鼠标移动事件。Java实用教程 监听者中有具体的方法分别针对上述具体的鼠标事件,系统能够自动分辨鼠标事件的类型并调用相应的方法,所以只需编码实现相应的代码就可以了。public int getButton() 返回哪个按钮发生变化。public int getClickCount() 返回与这个事

289、件相关的鼠标单击的次数。public Point getPoint() 返回同源部件相对的事件发生的x、y位置。public int getX() 返回同源部件相对的事件发生的x位置。public int getY()返回同源部件相对的事件发生的y位置。Java实用教程 【例7.6】测试按钮和画布的鼠标事件,包括单击、按下、进入和退出等。鼠标事件的演示如图7.12和7.13所示。源程序代码如下:/程序文件名UseMouseEvent.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.ap

290、plet.Applet;public class UseMouseEvent extends Applet implements MouseListener, MouseMotionListenerJava实用教程Button btn;public void init() btn = new Button(演示鼠标事件); add(btn); /给按钮添加鼠标事件和鼠标移动事件 btn.addMouseListener(this); btn.addMouseMotionListener(this); /给画布添加鼠标事件和鼠标移动事件 this.addMouseListener(this);

291、this.addMouseMotionListener(this);Java实用教程/单击事件public void mouseClicked(MouseEvent e)Point p = new Point();if(e.getSource() = btn)if(e.getClickCount() = 1)btn.setLabel(单击鼠标);else if(e.getClickCount() = 2)btn.setLabel(双击鼠标);Java实用教程elseif(e.getClickCount() = 1)p = e.getPoint();showStatus(p.x + , + p.

292、y + 单击鼠标);else if(e.getClickCount() = 2)p = e.getPoint();showStatus(p.x + , + p.y + 双击鼠标);Java实用教程 /进入事件public void mouseEntered(MouseEvent e)if(e.getSource() = btn)btn.setLabel(进入Button);elseshowStatus(进入Applet);public void mouseExited(MouseEvent e)if(e.getSource() = btn)btn.setLabel(退出Button);Java

293、实用教程elseshowStatus(退出Applet);/按下事件public void mousePressed(MouseEvent e)if(e.getSource() = btn)btn.setLabel(按下鼠标);elseshowStatus(按下鼠标);/释放事件public void mouseReleased(MouseEvent e)Java实用教程if(e.getSource() = btn)btn.setLabel(松开鼠标);elseshowStatus(松开鼠标);/移动事件public void mouseMoved(MouseEvent e)if(e.getS

294、ource() = btn) btn.setLabel(移动鼠标);else showStatus(移动鼠标,新位置 + e.getX() + , + e.getY();Java实用教程/拖动事件public void mouseDragged(MouseEvent e)if(e.getSource() = btn)btn.setLabel(拖动鼠标);elseshowStatus(拖动鼠标);Java实用教程图7.12 状态行提示鼠标移动位置 Java实用教程图7.13 提示“按下鼠标”Java实用教程7.2.6 键盘事件键盘事件(KeyEvent) 键盘事件有三个:键盘按键按下,按键释放,

295、按键被敲击。常用方法如下:public char getKeyChar() 返回事件中键的字符。public int getKeyCode() 返回整数键码。public static String getKeyText(int keyCode) 返回描述这个键码的字符串,例如“HOME”、“F1”或者“A”等。public interface KeyListener extends EventListener用来接收键盘事件。使用方法addKeyListener注册。Java实用教程针对键盘的三个事件接口提供相应的方法进行处理,具体方法如下:public void keyPressed(Ke

296、yEvent e) 按键时引发事件处理。public void keyReleased(KeyEvent e) 释放键时引发事件处理。public void keyTyped(KeyEvent e) 键入键时引发事件处理。Java实用教程例如,按键处理事件如下:public void keyPressed(KeyEvent e)char ch = e.getKeyChar();if(ch =Y | ch = y)txt.setText (同意);else if ch = N | ch = n ()txt.setText (反对);elsetxt.setText (无效);Java实用教程7.3

297、 多多 线线 程程 机机 制制7.3.1 线程简介线程简介 线程(thread)就是进程中的一个执行线索。Java虚拟机允许进程中同时执行多个线程。每个线程都有一个优先级。具有较高优先级的线程先执行。线程是操作系统分配 CPU 时间的基本实体。每一个应用程序至少有一个线程,也可以拥有多个线程。线程是程序中的代码流。多个线程可以同时运行并能共享资源。 线程与进程不同,每个进程都需要操作系统为其分配独立的地址空间,而同一进程中的各个线程是在同一块地址空间中工作。 在 Java 程序中,一些动态效果(如动画的实现、动态的字幕等)常利用多线程技术来实现。Java实用教程 线程存在一个生命周期,由以下方

298、法体现:(1) start()方法:启动一个线程。(2) run()方法:定义该线程的动作。(3) sleep()方法:使线程睡眠一段时间,单位为ms。(4) suspend()方法:使线程挂起。(5) resume()方法:恢复挂起的线程。(6) yield()方法:把线程移到队列的尾部。(7) stop()方法:结束线程生命周期并执行清理工作。(8) destroy()方法:结束线程生命周期但不做清理工作。 其中最常用的是方法start()、run()、sleep()、stop()。Java实用教程7.3.2 线程类和线程类和Runnable接口接口1. 建立建立Thread类的子类类的子

299、类 class myThread extends Thread .public void start()/启动线程 .public void run()/运行线程.Java实用教程 【例7.7】多线程实例,主函数给予调用,调用情况如图7.14所示。源程序代码如下:public class MThread public static void main(String args) System.out.println(Hello World!);thread2 t1 = new thread2(线程实例1); /创建线程实例t1.start(); /调用thread2 t2 = new threa

300、d2(线程实例2);t2.start();thread2 t3 = new thread2(线程实例3);t3.start(); Java实用教程/自定义线程类thread2class thread2 extends ThreadThread thread; /定义线程实例String str;/构造函数public thread2(String str)this.str = str;/启动线程public void start()thread = new Thread(this);thread.start();Java实用教程public void run()int i = 0;while(

301、thread != null)try/计数到5时睡眠10秒if(i = 5)sleep(10000);catch(Exception e)Java实用教程System.out.println(e.getMessage(); System.out.println(str); i+; ;Java实用教程图7.14 多线程操作界面Java实用教程 2. 实现接口实现接口Runnable public interface Runnable Runnable接口可以由任意试图实现线程机制的类来实现。接口包含一个run方法。 public void run() 对象实现Runnable接口时,创建一个线程

302、,启动线程导致对象run方法的调用。 实现接口Runnable进行多线程设计的方法较为常用。下面给出一个例子。Java实用教程 【例7.8】编写Applet,实现Runnable接口进行简单的动画演示:三幅图片依次上移,如图7.15所示。源程序代码如下:/程序文件名为UseRunnable.javaimport java.awt.*;import java.applet.Applet;public class UseRunnable extends Applet implements RunnableThread t;Image imgs;int high,h1,h2,h3;public vo

303、id init()Java实用教程 high = getHeight()/3; h1 = high; h2 = high * 2; h3 = high * 3; imgs = new Image3; for (int i = 0; i 3; i +) imgsi = getImage(getDocumentBase(),image + (i+1) + .gif); public void start()Java实用教程t = new Thread(this);t.start();public void stop()t = null;/实现接口的run方法,获得动画效果public void r

304、un()while( t != null)tryJava实用教程Thread.sleep(100);repaint();h1 -;/上移,到顶点时睡眠if(h1 = 0)Thread.sleep(3000);h2 = high;/上移,到顶点时睡眠h2 -;if(h2 = 0)Thread.sleep(3000); h3 = high;Java实用教程/上移,到顶点时睡眠h3-;if(h3 = 0)Thread.sleep(3000);h1 = high; catch(InterruptedException e) System.out.println(e.getMessage(); Java

305、实用教程public void paint(Graphics g)/三幅图片依次显示g.drawImage(imgs0,0,h1,this);g.drawImage(imgs1,0,h2,this);g.drawImage(imgs2,0,h3,this);public void update(Graphics g)paint(g);Java实用教程图7.15 动画界面Java实用教程习习 题题 1. 自定义一个用户异常,用于数值运算时在输入的字符中检测非数字字符,并编写抛出异常时的提示“使用非法字符”,测试异常。 2. 为第6章习题1中图6.12所示的“提交”按钮添加动作事件,用来收集界面上

306、输入的个人信息,并在原有界面上添加一个文本区域,将数据输出到文本区域中。 3. 为第6章习题2添加调整事件,使得三个滚动条进行滑动时,标签的颜色相应地发生变化。 4. 编写Applet,实现Runnable接口,使得界面上的一图片持续做水平运动。Java实用教程第8章 输入输出技术 8.1 流式输入输出流式输入输出8.2 基本输入输出流基本输入输出流8.3 文件处理类文件处理类8.4 对象流对象流 习习 题题 Java实用教程8.1 流式输入输出流式输入输出 所有的计算机程序都必须接收输入和产生输出。针对输入、输出,Java提供了丰富的类库进行相应的处理,包括从普通的流式输入输出到复杂的文件随

307、机访问。计算机系统使用的信息都是从输入经过计算机流向输出。这种数据流动就称为流(Stream)。输入流指数据从键盘或者文件等输入设备流向计算机;输出流指数据处理结果从计算机流向屏幕或文件等输出设备。Java实用教程 在Java中,通过java.io包提供的类来表示流,基本的输入输出流为InputStream和OutputStream。从这两个基本的输入输出流派生出面向特定处理的流,如缓冲区读写流、文件读写流等。Java定义的流如表8.1所示。 表表8.1 Java定义的输入输出流定义的输入输出流Java实用教程8.2 基本输入输出流基本输入输出流8.2.1 InputStream类类 Inpu

308、tStream是抽象类,代表字节输入流的所有类的超类。这个类本身不能使用,只能通过继承它的具体类完成某些操作。它的常用方法如下: public int available() throws IOException 返回流中可用的字节数。 public void close() throws IOException 关闭流并释放与流相关的系统资源。用户使用完输入流时,调用这个方法。 public void mark(int readlimit) throws IOException 输入流中标志当前位置。Java实用教程 public boolean markSupported() throws

309、 IOException 测试流是否支持标志和复位。 public abstract int read() throws IOException 读取输入流中的下一个字节。 public int read(byte b) throws IOException 从输入流中读取字节并存储到缓冲区数组b中,返回读取的字节数,遇到文件结尾返回-1。Java实用教程 public int read(byte b, int off, int len) throws IOException 从输入流中读取len个字节并写入b中,位置从off开始。返回写的字节数。 public void reset() th

310、rows IOException 重定位到上次输入流中调用的位置。 public long skip(long n) throws IOException 跳过输入流中n个字节,返回跳过的字节数,遇到文件结尾返回-1。Java实用教程8.2.2 OutputStream类类OutputSteam是抽象类,代表输出字节流的所有类的超类。public void close() throws IOException关闭输出流,释放与流相关的系统资源。 public void flush() throws IOException 清洗输出流,使得所有缓冲区的输出字节全部写到输出设备中。 public

311、void write(byte b) throws IOException 从特定字节数组b将b数组长度个字节写入输出流。 public void write(byte b, int off, int len) throws IOException 从特定字节数组b将从off开始的len个字节写入输出流。 public abstract void write(int b) throws IOException向输出流写一个特定字节。Java实用教程8.2.3 系统输入输出对象系统输入输出对象 Java定义了两个流对象System.in和System.out,允许用户在自己的程序中直接使用。Sy

312、stem.in对象允许用户从键盘读取数据,System.out对象可以产生屏幕输出。 【例8.1】使用流对象System.in和System.out,接收用户从键盘上输入的数据并将数据输出到屏幕上。测试情况如图8.1所示。源程序代码如下:/程序文件名为SystemIO.javaimport java.io.*;public class SystemIO Java实用教程public static void main(String args)int bytes = 0;byte buf = new byte255;System.out.println(n请输入任意文本:);try /接收输入字符

313、串bytes = System.in.read(buf,0,255);System.out.println(这是你输入的文本行:);String inStr = new String(buf,0,bytes);Java实用教程/输出字符串System.out.println(inStr);catch(IOException e)System.out.println(e.getMessage(); ;Java实用教程图图8.1 例例8.1的屏幕显示的屏幕显示Java实用教程8.3 文文 件件 处处 理理 类类8.3.1 FileInputStream类类 FileInputStream(文件输入

314、流)类是用来得到文件的输入字节流。大部分方法继承于InputStream类。它的构造方法如下: FileInputStream(File file) 通过打开一个到实际文件的链接,创建一个文件输入流,参数file是一个文件对象。 FileInputStream(String name) 通过打开一个到实际文件的链接,创建文件输入流,参数name为文件的实际路径。Java实用教程 【例8.2】使用FileInputStream对象打开源程序文件,源文件的输出如图8.2所示。源程序代码如下:/程序文件名为UseFileInputStream.javaimport java.io.*;public

315、class UseFileInputStream public static void main(String args)byte buf = new byte2056;try /构造文件输入流Java实用教程FileInputStream fileIn = new FileInputStream(UseFileInputStream.java); /存入缓冲bufint bytes = fileIn.read(buf,0,2056);String inStr = new String(buf,0,bytes); /输出文件内容System.out.println(inStr); catch(

316、IOException e) System.out.println(e.getMessage(); ;Java实用教程图8.2 输出源文件内容Java实用教程8.3.2 FileOutputStream类类 FileOutputStream(文件输出流)类是将数据写入File或 FileDescriptor对象的输出流。它的方法大都是从OutStream继承来的,其构造方法如下: FileOutputStream(File file) 创建输出流写到特定的file对象。 FileOutputStream(File file, boolean append) 以追加的方式写入file对象。 Fi

317、leOutputStream(FileDescriptor fdObj) 创建输出文件流到fdObj对象,代表一个到实际文件的链接。 Java实用教程FileOutputStream(String name) 创建输出流,写到指定的name文件。FileOutputStream(String name, boolean append) 是否以追加的方式写到指定的name文件。Java实用教程 【例8.3】使用FileOutputStream对象,打开一个文件,写入一行文本,然后追加一行从键盘接收的字符串(如图8.3的上部分所示),文件内容如图8.3的下部分所示。源程序代码如下:/程序文件名为U

318、seFileOutputStream.javaimport java.io.*;public class UseFileOutputStream public static void main(String args)byte buf = new byte255;byte bufIn = new byte255;Java实用教程tryString str = 你好,这是已有的文本;buf = str.getBytes(); /创建文件输出流对象FileOutputStream fileOut = new FileOutputStream(Hello.txt); /写入文件fileOut.wri

319、te(buf,0,buf.length);fileOut.flush();fileOut.close();Java实用教程System.out.println(n请输入一行文本:); /从键盘接收文本int bytes = System.in.read(bufIn,0,255); /追加文本fileOut = new FileOutputStream(Hello.txt,true);fileOut.write(bufIn,0,bytes); catch(IOException e) System.out.println(e.getMessage(); ;Java实用教程图8.3 程序运行和写入

320、的文件内容Java实用教程8.3.3 File类类 用户接口和操作系统使用依赖于系统的路径字符串来命名文件和目录。File类就表示这些文件和目录路径,它代表一个抽象的依赖于系统的层次路径视图。File类允许用户向系统查询该文件的所有信息,也可以使用类来创建新的目录或者删除和重命名文件。 当用户需要获得有关文件的信息时,就需要创建一个File类,而当File类用于文件读写时,通常与FileInputStream流相结合。Java实用教程 【例8.4】创建一个临时文件,写入一行数据,然后删除。临时文件的周期说明如图8.4所示。源程序代码如下:/程序文件名为UseFile.javaimport ja

321、va.io.*;public class UseFile public static void main(String args)tryJava实用教程File f = new File(temp.txt);System.out.println(创建临时文件);FileOutputStream fout = new FileOutputStream(f);PrintStream p = new PrintStream(fout);p.println(将这句话放入临时文件);System.out.println(写临时文件);f.deleteOnExit();System.out.println

322、(删除临时文件);catch(IOException e)System.out.println(e.getMessage(); ;Java实用教程图8.4 临时文件的周期说明Java实用教程8.3.4 RandomAccessFile类类 RandomAccessFile(随机访问文件)类的实例支持对随机访问文件的读/写。随机访问文件就像存储在文件系统中的巨大的字节数组,通过游标或者索引(叫做文件指示器)指向这个暗含的数组,输入操作从指示器处读取字节,然后前进指针。如果随机访问文件以可读/写模式创建,那么还支持输出操作,输出操作写到暗含数组的尾端,使得数组得以扩展。Java实用教程 【例8.5

323、】随机访问文件,将文件内容输出,并写入两个字符“O”、“K”。文件内容显示如图8.5的下半部分所示,若文件内容直接输出到屏幕上,则出现如图8.5上半部分所示的乱码问题,添加一个parseChinese方法后,得以修正,输出结果如图8.6所示。源程序代码如下:/程序文件名为UseRandom.javaimport java.io.*;public class UseRandom public static void main(String args)Java实用教程try /构建随机访问文件对象 RandomAccessFile f = new RandomAccessFile(Hello.tx

324、t,rw); /得到文件指针和长度 long flag = 0; long len = f.length(); /字符处理后输出 while(flag len) Java实用教程String s = f.readLine();System.out.println(parseChinese(s);flag = f.getFilePointer(); /末尾写入字符f.writeChar(O);f.writeChar(K);catch(IOException e)System.out.println(e.getMessage();Java实用教程/解决中文转换问题public static Str

325、ing parseChinese(String inStr) String s = null; byte temp; if (inStr = null) return new String(); try temp=inStr.getBytes(iso-8859-1); Java实用教程s = new String(temp); catch(UnsupportedEncodingException e) System.out.println (e.toString(); return s; ;Java实用教程图8.5 文件内容及屏幕输出Java实用教程图8.6 字符处理后的屏幕输出Java实用教

326、程8.4 对对 象象 流流8.4.1 ObjectInputStream类类 ObjectInputStream(对象输入流)可读取使用对象输出流写入的原始数据和类型,与文件输入输出流一起可以实现对象的持久性存储。它的构造函数和一个读对象的方法如下: public ObjectInputStream(InputStream in) throws IOException 从特定的输入流中读取并创建一个对象输入流。 Public Object readObject() 从对象输入流中读取对象。Java实用教程8.4.2 ObjectOutputStream类类 ObjectOutputStream

327、(对象输出流)可将Java的原始数据类型和图形写入输出流,对象可以使用对象输入流读取,使用文件可以实现对象的持久存储。它的构造函数和一个写对象方法如下: public ObjectOutputStream(OutputStream out) throws IOException 创建一个对象输出流,可以写入特定的输出流。 void writeObject(Object obj) 将对象obj写入对象输出流。Java实用教程 【例8.6】将日期对象和向量对象写入文件,然后从文件中读出并输出到屏幕上,输出结果如图8.7所示。要求向量对象含有三个值“语文”、“数学”和“物理”。源程序代码如下:/程序

328、文件名为UseStream.javaimport java.io.*;import java.util.*;public class UseStream extends Objectpublic static void main(String args)Java实用教程 /构建Vector对象Vector v = new Vector();v.add(语文);v.add(数学);v.add(物理);try /文件处理对象File f = new File(temp.txt);FileOutputStream fOut = new FileOutputStream(f);ObjectOutput

329、Stream objOut = new Java实用教程ObjectOutputStream(fOut); /写入日期对象objOut.writeObject(new Date(); /写入Vector对象objOut.writeObject(v);objOut.close(); /构建readObj的实例readObj rObj = new readObj(); /调用方法输出rObj.readO(); catch(IOException e) Java实用教程System.out.println(e.getMessage(); ;/自定义类,实现读取对象并输出class readObj e

330、xtends Object public void readO() try /文件处理对象File f = new File(temp.txt);Java实用教程FileInputStream fIn = new FileInputStream(f);ObjectInputStream objIn = new ObjectInputStream(fIn); /读取对象输出Object ob1 = objIn.readObject();System.out.println(ob1);Object ob2 = objIn.readObject();System.out.println(ob2);

331、catch(IOException e) Java实用教程System.out.println(e.getMessage();catch(ClassNotFoundException e)System.out.println(e.getMessage(); ;Java实用教程图8.7 对象输出Java实用教程习习 题题 1 编写一个一位数算术表达式计算器,要求用户从命令提示符下输入表达式,如5*4,程序返回结果5*4 20。循环提示,直至用户输入“$”符号终止程序。【提示:程序解析表达式,得出操作数和操作符,进行运算后返回结果。】要求程序交互提示如下:程序提示:请输入一位数表达式用户输入:3+

332、2程序返回:3+2 5程序提示:请输入一位数表达式用户输入:$程序退出:退出系统Java实用教程 2. 编写应用程序,界面如图8.8所示。当用户在第一个文本框内填入文件的路径后单击“打开文件”按钮,文件的内容显示在下面的文本区域内,在文本区域内对文件做出修改后,单击“存储文件”按钮,则可以将文件存入原来的文件名中。图8.8 用户界面Java实用教程 3. 编写应用程序,界面如图8.8所示,首先在文本框中输入一个新文件名称,单击“存储文件”按钮时,使用Hashtable对象存储以下键-值对 语文 89;数学 98;英语 90并将此Hashtable对象写入“文件名”标识的新文件中,然后单击“打开

333、文件”按钮,完成以下操作:打开文件,读出对象,在文本区域中顺序输出分数。Java实用教程第9章 Java数据库技术 9.1 JDBC概述概述9.2 使用使用JDBC 9.3 实例实例 习习 题题 Java实用教程9.1 JDBC概述概述 JDBC(Java Database Connection,Java数据库连接)是一种用于执行SQL语句的JavaAPI(应用程序设计接口),它由一些Java语言写的类和界面组成。JDBC提供了一种标准的应用程序设计接口,使得开发人员使用Java语言开发完整的数据库应用程序变得极为简单。通过JDBC,开发人员几乎可以将SQL语句传递给任何一种数据库,而无需为各

334、种数据库编写单独的访问程序。JDBC可以自动将SQL语句传递给相应的数据库管理系统。Java实用教程 JDBC扩展了Java的功能,例如在Applet中应用JDBC,可以实现与远程数据库的连接,实现不同平台数据库之间的对话。简单地说,JDBC完成下面三个操作: (1) 与一个数据库建立连接。 Connection con = DriverManager.getConnection(jdbc:odbc:CallCenter,sa,); (2) 向数据库发送SQL语句。 stmt = con.createStatement();rs = stmt.executeQuery(SELECT CID,C

335、Pin from tCustomer WHERE CID=z1); Java实用教程(3) 处理数据库返回的结果。while(rs.next()String theInt = rs.getString(CID);String str = rs.getString(CPin); .Java实用教程9.2 使使 用用JDBC JDBC的接口分为两个层次:一个是面向程序开发人员的JDBC API;另外一个是底层的JDBC Driver API。JDBC API 被描述成为一组抽象的Java接口,应用程序可以对某个数据库打开连接,执行SQL语句并且处理结果。最重要的接口如下: java.sql.Dri

336、verManager:处理驱动的调入并且对产生新的数据库连接提供支持。 java.sql.Connection:代表对特定数据库的连接。 java.sql.Statement:代表一个特定的容器,以对一个特定的数据库执行SQL语句。 java.sql.ResultSet:控制对一个特定语句的行数据的存取。Java实用教程 其中java.sql.Statement又有两个子类型: (1) java.sql.PreparedStatement:用于执行预编译的SQL语句。 (2) java.sql.CallableStatement:用于执行对一个数据库内嵌过程的调用。 JDBC Driver A

337、PI是指java.sql.Driver接口,封装了不同数据库的驱动程序(像Access、Foxpro、SQL Server等)。由于它是数据库底层处理,所以必须提供对java.sql.Connection、java.sql. Statement、java.sql.PreparedStatement和java.sql.ResultSet的实现。Java实用教程 如果目标DBMS提供有OUT参数的内嵌过程,那么还必须提供java.sql.CallableStatement 接口。在java.sql.Driver接口中每个数据库驱动程序必须提供一个类,使得系统可以由 java.sql.DriverM

338、anager来管理。一个比较好用的驱动程序是在ODBC之上提供对JDBC的实现,从而提供与ODBC接口的JDBC-ODBC 桥。所谓JDBC-ODBC桥,是一个JDBC驱动程序,通过将JDBC操作转换为ODBC操作来实现JDBC操作。它由sun.jdbc.odbc包实现,包含一个用来访问ODBC的本地库,对所有ODBC可用的数据库实现JDBC。 Java实用教程 通过ODBC子协议,可以使用下面一行代码进行显示加载。 Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); 加载时,ODBC驱动程序将创建自己的实例,同时在JDBC驱动程序管理器中进行注册。由于J

339、DBC放在ODBC之后,所以实现起来简单且高效。Java实用教程9.2.1 Driver Driver接口是每个驱动器类都需要完成的。JavaSQL框架允许有多个数据库驱动器,每个驱动器应该提供一个类来实现驱动器接口,而驱动器的装载通过DriverManager实例实现。 DriverManager将装载尽量多的驱动器,对每个给定的连接请求,将所有的驱动器依次连接到目标数据库上。当驱动器类装载后,Driver应该创建一个实例,然后注册到DriverManager上。Java实用教程9.2.2 DriverManager DriverManager管理一系列JDBC驱动器的基本服务。应用程序可以

340、显式加载JDBC驱动器。例如下面代码显式加载my.sql.Driver。 Class.forName(my.sql.Driver); 显式加载JDBC-ODBC桥: Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);Java实用教程它的较为重要的方法有: public static Connection getConnection(String url) throws SQLException public static Connection getConnection(String url, Properties info) throws SQLExce

341、ption public static Connection getConnection(String url, String user, String password) throws SQLException 这些方法的功能都是建立一个到给定数据库url的连接。DriverManager试图从注册的JDBC驱动器序列中选择合适的驱动器,返回到url的连接。Java实用教程 其中: (1) url为数据库url,格式为 jdbc:subprotocol:subname。 (2) info以“标记/数值对”作为连接参数,至少应该包括user和password属性对。 (3) user指数据库用

342、户(连接以什么身份建立)。 (4) password 是用户的密码。 例如:使用JDBC-ODBC桥建立到ODBC配置的数据库CallCenter的连接,访问CallCenter数据库的用户名为sa,密码无。语句行如下:Connection con = DriverManager.getConnection(jdbc:odbc:CallCenter,sa,); Java实用教程9.2.3 Connection 一个Connection(连接)就是一个与特定数据库的会话。在连接的上下文环境中才可以执行SQL语句和返回结果。Connection对象的数据库可以提供描述它的表、SQL语法和存储过程等

343、的信息。它较为重要的方法有: public Statement createStatement() throws SQLException 创建一个Statement对象,用于发送SQL语句到数据库。没有参数的SQL语句通常使用Statement对象执行。如果希望多次执行,使用PreparedStatement更为高效。 Java实用教程 public PreparedStatement prepareStatement(String sql) throws SQLException 创建一个PreparedStatement对象,发送参数化SQL语句sql到数据库。 SQL语句可以预先编译并

344、存储到PreparedStatement语句中。这个对象可以用来高效地多次执行语句。 其中:参数sql是包含多个“?”参数的SQL语句,“?”表示输入参数由用户进行设置。 Java实用教程 例如: 创建Statement对象语句如下: stmt = con.createStatement(); 创建PreparedStatement对象语句如下: pstmt = con.prepareStatement(UPDATE Xuesheng SET 班级 = ? WHERE 班级 = ?);Java实用教程9.2.4 Statement Statement对象用于执行一个静态的SQL语句并返回它产生

345、的结果。在缺省情况下,任一时刻每个Statement对象只产生一个ResultSet集。对数据库希望有不同操作得到结果集时,需要创建不同的Statement对象。它的较为重要的方法有: public ResultSet executeQuery(String sql) throws SQLException 执行给定的sql语句,返回一个ResultSet对象。 Java实用教程 public int executeUpdate(String sql) throws SQLException 执行给定的sql语句,可以是插入(INSERT)、更新(UPDATE)或者删除(DELETE)等,也可

346、以是一个空语句,执行DDL语句。返回值是操作的记录个数。 public ResultSet getResultSet() throws SQLException 以ResultSet对象格式返回当前结果集,每个结果集只调用一次。 例如: 从表tCustomer中返回CID为z1的记录的CID(客户ID)和CPin(密码)列,语句行为:rs = stmt.executeQuery(SELECT CID,CPin from tCustomer WHERE CID= z1 );Java实用教程9.2.5 PreparedStatement PreparedStatement代表预编译的SQL语句的对

347、象。一个SQL语句预编译后存储到PreparedStatement对象中,这个对象用来多次执行语句。PreparedStatement继承于Statement,扩展了Statement的用途,提高了Statement的执行效率。它与Statement对象有两点不同:(1) 同一个对象可以多次使用。(2) 它的SQL语句可以带输入(IN)参数。Java实用教程 PreparedStatement在程序语句中的输入参数使用占位符“?”来实现。必须使用类提供的设置方法设置语句中占位符的具体值,才能执行语句。如下面的程序段,根据ID的取值更新EMPLOYEES表中SALARY字段的取值,将第一个占位符

348、代表的参数设置为10000.00,将第二个占位符代表的参数设置为111,语句执行的结果是EMPLOYEES表中ID为111的记录的SALARY取值为10000.00。Java实用教程 PreparedStatement pstmt = con.prepareStatement(UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?); pstmt.setBigDecimal(1, 10000.00) pstmt.setInt(2, 111); pstmt.executeUpdate(); 类PreparedStatement提供的常用方法如下: public

349、boolean execute() throws SQLException 执行PreparedStatement对象中的任一类型的SQL语句。如果返回true,则调用getResultSet方法取得ResultSet集;如果返回false,则调用getUpdateCount方法获得更新数。Java实用教程 public ResultSet executeQuery() throws SQLException 执行SQL查询,并返回查询产生的结果集。 public int executeUpdate() throws SQLException 执行对象中的SQL语句。如果是一些更新操作,如插入

350、(INSERT)、修改(UPDATE)和删除(DELETE )等,则返回操作的个数。Java实用教程常用的设置方法为:public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException 在第parameterIndex位置设置BigDecimal型x。public void setBoolean(int parameterIndex, boolean x) throws SQLException 在第parameterIndex位置设置布尔型x。public void setByte(int param

351、eterIndex, byte x) throws SQLException在第parameterIndex位置设置字节型x。Java实用教程public void setBytes(int parameterIndex, byte x) throws SQLException在第parameterIndex位置设置字节数组型x。public void setDouble(int parameterIndex, double x) throws SQLException在第parameterIndex位置设置双精度型x。public void setFloat(int parameterInd

352、ex, float x) throws SQLException 在第parameterIndex位置设置单精度型x。public void setInt(int parameterIndex, int x) throws SQLException 在第parameterIndex位置设置整型x。Java实用教程public void setLong(int parameterIndex, long x) throws SQLException在第parameterIndex位置设置长整型x。public void setNull(int parameterIndex, int sqlType

353、) throws SQLException 在第parameterIndex位置设置为空x。public void setObject(int parameterIndex, Object x) throws SQLException 在第parameterIndex位置设置对象x。public void setShort(int parameterIndex, short x) throws SQLException 在第parameterIndex位置设置短整型x。Java实用教程void setString(int parameterIndex, String x) throws SQL

354、Exception 在第parameterIndex位置设置字符串型x。public void setTime(int parameterIndex, Time x) throws SQLException 在第parameterIndex位置设置时间型x。public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException在第parameterIndex位置设置时间戳型x。Java实用教程9.2.6 ResultSet Result对象是指一张数据表,代表数据库结果集,通常是通过执行查询数据库的语句而产生的

355、。ResultSet对象持有一个游标,该游标指向当前数据行。初始化时游标定位到第一行之前。Next方法将游标移动到下一行,当对象行完时,返回错误。通常使用循环来完成每行的遍历。 public boolean next() throws SQLException 读行,返回true;行数完,则返回false。Java实用教程 例如,下面程序段完成对结果集的操作,对所有记录进行遍历并输出其中的字段CID和CPin的值。while(rs.next()String theInt = rs.getString(CID);String str = rs.getString(CPin);System.out

356、.println(CID: +theInt+ CPin: +str);Java实用教程 结果集有一些方法用于对返回结果的具体字段进行读取,包括以字段编号为参数和以字段名称为参数的读取,其中以字段编号为参数的读取速度快一些,而以字段名称为参数的读取对用户来说更加方便。 所谓字段编号是指当前结果集中的第一个列字段编号为1,然后依次加1对剩余列进行编号;而字段名称是指列标题的名字。Get字段的类型同上述Set字段的类型一致。下面是以字段编号为参数的读取方法:Java实用教程public BigDecimal getBigDecimal(int columnIndex) throws SQLExcep

357、tion public boolean getBoolean(int columnIndex) throws SQLException public byte getByte(int columnIndex) throws SQLExceptionpublic byte getBytes(int columnIndex) throws SQLExceptionpublic double getDouble(int columnIndex) throws SQLExceptionpublic float getFloat(int columnIndex) throws SQLException

358、public Int getInt(int columnIndex) throws SQLExceptionpublic Long getLong(int columnIndex) throws SQLExceptionJava实用教程public Object getObject(int columnIndex) throws SQLException public short getShort(int columnIndex) throws SQLException public String getString(int columnIndex) throws SQLException p

359、ublic java.sql.Time getTime(int parameterIndex, Time x) throws SQLException public java.sql.TimeStamp getTimestamp(int columnIndex) throws SQLExceptionJava实用教程以字段名称为参数的读取方法如下:public BigDecimal getBigDecimal(String columnName) throws SQLException public boolean getBoolean(String columnName) throws SQ

360、LException public byte getByte(String columnName) throws SQLExceptionpublic byte getBytes(String columnName) throws SQLExceptionpublic double getDouble(String columnName) throws SQLExceptionpublic float getFloat(String columnName) throws SQLException public Int getInt(String columnName) throws SQLEx

361、ception Java实用教程public Long getLong(String columnName) throws SQLExceptionpublic Object getObject(String columnName) throws SQLException public short getShort(String columnName) throws SQLException public String getString(String columnName) throws SQLException public java.sql.Time getTime(String col

362、umnName) throws SQLException public java.sql.TimeStamp getTimestamp(String columnName) throws SQLExceptionJava实用教程9.3 实实 例例 【例9.1】给出一个完整的实例,包括建立所需用户数据库,配置ODBC数据源,编写访问数据库的程序,查看运行结果。其中访问数据库程序输出班级为“025”的记录,并将“025”修改为“计算机”。Java实用教程9.3.1 建立用户数据库建立用户数据库 建立FoxPro数据库,数据库名为Student.mdb,其中一个表为Xuesheng.dbf,记录如图

363、9.1所示。图9.1 表Xuesheng.dbf中的记录Java实用教程9.3.2 配置配置ODBC数据源数据源 在Windows 2000下配置ODBC数据源,首先找到程序管理工具数据源(ODBC),(在Windows 98下,可在控制面板中找到ODBC),调出“ODBC数据源管理器”,如图9.2所示。图9.2 ODBC数据源管理器Java实用教程点击“添加”按钮,出现 “创建新数据源” 窗口,如图9.3所示。图9.3 为数据源选择驱动程序Java实用教程 在图9.3中选择“Microsoft Visual FoxPro Driver”选项,然后点击“完成”按钮,进入“ODBC Visual

364、 FoxPro Setup”窗口,如图9.4所示。图9.4 完成ODBC数据源的配置Java实用教程 (1) “Data Source Name (数据源名)”:ODBC提供给应用程序的数据库名字。在图9.4中填为STU。 (2) “Description (描述)”:用来说明数据库的文字信息,可根据自己的需要填写。在图9.4中填为“用于JAVA程序的数据库测试”。 (3) “Path (路径)”是ODBC映射数据库的具体路径,可以直接填写,也可以单击“Browse”(浏览)按钮选择一数据库。这里选择的路径为E:_WorkJavaSTUDENT.DBC。 (4) 点击“OK (确定) ”按钮,

365、可以看见“ODBC数据源管理器”窗口多出一个STU数据源。Java实用教程9.3.3 数据库访问的步骤数据库访问的步骤编写数据库访问程序的步骤如下:(1) 引入java.sql的包。import java.sql.*;(2) 声明变量。Statement stmt;PreparedStatement pstmt;ResultSet rs;Java实用教程(3) 加载驱动程序。Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);(4) 连接数据库。String urlName = jdbc:odbc:STU;Connection con = DriverMan

366、ager.getConnection(urlName,);Java实用教程(5) 执行查询操作。rs = stmt.executeQuery(SELECT 学号,姓名,班级 from Xuesheng WHERE 班级=025);.pstmt = con.prepareStatement(UPDATE Xuesheng SET 班级 = ? WHERE 班级 = ?);pstmt.setString(1,计算机);pstmt.setString(2,025);pstmt.executeUpdate();. (6) 关闭数据库。 con.close();Java实用教程9.3.4 源程序代码源程

367、序代码源程序代码如下:/程序文件名UseJDBC.javaimport java.sql.*;public class UseJDBCpublic static void main(String args)tryJava实用教程Statement stmt;PreparedStatement pstmt;ResultSet rs;/加载JDBC-ODBC桥Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);String urlName = jdbc:odbc:STU; /连接STU数据库 Connection con = DriverManager.getC

368、onnection(urlName,); /执行sql查询stmt = con.createStatement();Java实用教程rs = stmt.executeQuery(SELECT 学号,姓名,班级 from Xuesheng WHERE 班级=025);System.out.println(显示所有返回结果:); /遍历结果集while(rs.next() /得到记录值,输出 String strNumber = rs.getString(学号); String strName = rs.getString(姓名); String strClass = rs.getString(3

369、);Java实用教程System.out.println(学号: + strNumber + 姓名: +strName + 班级: +strClass); /更新班级值pstmt = con.prepareStatement(UPDATE Xuesheng SET 班级 = ? WHERE 班级 = ?);pstmt.setString(1,计算机);pstmt.setString(2,025);pstmt.executeUpdate(); /关闭连接Java实用教程con.close();catch(Exception e)e.printStackTrace();Java实用教程9.3.5

370、运行结果运行结果 在图9.5中,输出“班级”为“025”的记录中的“学号”、“姓名”和“班级”字段。图9.6为执行更新操作后的表记录。与图9.1相比,可以看到程序操作以前为“025”的“班级”的列值已经更新为“计算机”。图9.5 界面输出Java实用教程图9.6 程序访问后的Xuesheng表Java实用教程习习 题题 1. 创建一个新的Access数据库或者其它类型的数据库,为之建立一个如图9.1所示的表stu。对数据库进行ODBC数据源配置,将它的名字配置成STUDENT。 2. 编写程序,访问习题1配置的STUDENT库中的表stu,输出所有女生的学号、姓名和班级,然后存到文件stu_f

371、emale中。 3. 编写程序,访问习题1配置的STUDENT库中的表stu,将学号以“02037”开头的学生的班级更新为“英语班”。 4. 编写Applet,实现到习题1配置的STUDENT库中的表stu的访问,界面上使用文本区域按行输出所有男生的记录。 Java实用教程第10章 Java安全技术 10.1 简介简介10.2 安全限制和许可安全限制和许可10.3 安全策略安全策略 (Policy)10.4 辅助工具辅助工具10.5 签名及发布的例子签名及发布的例子 习习 题题 Java实用教程10.1 简简 介介 Java是网络上使用的编程语言,安全性是非常重要的,特别是Java平台的安全以

372、及Java技术部署带来的安全问题,尤其值得认真考虑。Java中的安全包括两个方面: (1) 提供安全且易于构建的Java平台,能够以安全模式运行Java实现的应用程序。 (2) 提供用于编程语言的安全工具和服务,实现较广泛的安全。Java实用教程 Java平台提供的原始安全模型称为沙箱模型(JDK1.0),该模型提供较窄环境沙箱来运行没有得到信任的代码。在沙箱模型中允许得到信任的本地代码访问重要资源,而没有经过信任的远程代码只能访问沙箱内的很少部分资源。在JDK1.1中引入签名Applet的概念,如果签名的密钥由接收Applet的客户端认为是可信任的,那么这个经过正确数字签名的Applet就可

373、以当作可信任本地代码访问重要资源。这里签名Applet和它的签名以JAR格式传送。随着发展,在原来沙箱模型的基础上引入新的安全体系,形成Java 2平台安全模型如图10.1所示。从图10.1中可以看出,不管本地还是远程,签名还是未签名的代码都统一到类加载器处,咨询安全策略,然后决定代码能够访问的资源。Java 2安全平台模型较之以前有了很大的改进,其主要特点如下:Java实用教程(1) 细粒度的访问控制。(2) 易于配置的安全策略。 (3) 易于扩展的访问控制结构。(4) 安全检查扩展到所有Java程序,包括应用程序和Applet。Java实用教程图10.1 Java 2平台安全模型Java实

374、用教程 图10.1中的多个沙箱模型可以看作有固定边界的保护域。所谓保护域是指一个对象集合,这些对象可以由安全策略中定义的一条规则直接访问。保护域分为系统域和应用程序域,受保护的资源,像文件系统、网络设施以及屏幕和键盘,只允许系统域进行访问,而应用程序域可以通过授权许可访问受保护资源。类加载器将本地或远程代码(Applet)载入的同时,策略文件给出域的划分和不同代码对不同域访问权限的许可,载入的类就根据域划分和权限许可来访问相应的域资源。图10.2为运行中类到域再到许可的映射。Java实用教程图10.2 类到域再到许可的映射Java实用教程10.2 安全限制和许可安全限制和许可 本地的代码类访问

375、系统资源时通常不会受到太大的限制,所以本章主要讨论从服务器下载到客户端的远程代码Applet访问客户端资源的情况。 Applet访问客户端资源时,由于Java内嵌的平台安全性机制受到较大的限制,通常表现在无法读写客户端的文件,无法采集客户端音频。例如,当Applet实现的是客户端和服务器端进行语音聊天时,客户端采集音频就会受到限制,还有无法启动客户端的Socket进行传输等。下面看一个文件访问受到安全限制的例子。Java实用教程 【例10.1】 编写一个用来读取客户端文件的Applet,客户端的文件路径及文件名为E:a.txt,文件内容为“你好,这是客户端的测试文件!”,如图10.3右部分所示

376、。将读出的文件内容显示在文本区域内,如果访问出错,异常信息也显示在文本区域内。/程序文件名:AppletSecurity.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.io.*;public class AppletSecurity extends Applet Java实用教程TextField fileNameField;TextArea fileArea;public void init() Label lblName=new Label(文件名:);Label lblCont

377、ext = new Label(文件内容:);fileNameField=new TextField(35);fileNameField.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)loadFile(fileNameField.getText(););fileArea=new TextArea(10,35);Java实用教程add(lblName);add(fileNameField);add(lblContext);add(fileArea);public void loadF

378、ile(String fileName)tryBufferedReader reader=new BufferedReader(new FileReader(fileName);String context = new String();Java实用教程while(context = reader.readLine()!=null)fileArea.append(context + n);reader.close();catch(IOException ie)fileArea.append(IO错误: + ie.getMessage();Java实用教程catch(SecurityExcept

379、ion se) fileArea.append(安全访问错误: + se.getMessage(); Java实用教程 程序编写后,编译生成相应的类,将类嵌入HTML文件,从本地服务器加载,在载入Applet的界面上输入文件名E:a.txt后按回车键,在界面的文本区域内并没有显示相应a.txt的内容,只是提示“access denied (java.io.FilePermission E:a.txt read)”,表示访问拒绝,如图10.3左部分所示。图10.3 Applet访问文件出错显示和客户端文件内容Java实用教程 Java安全平台中受到的种种安全限制,在Java中都提供了一一对应的许

380、可,例如对于读、写文件的限制,Java提供了java.io.FilePermission来许可对客户端文件的读、写等操作。下面看一下这些许可类。 许可类代表对系统资源的访问权限。Java.security.permission类是抽象类,划分为多个子类来代表特定的访问。而不同的许可类属于不同的包,如FilePermission类属于java.io包,而SocketPermission类属于包。目前Java系统内嵌的主要的许可类如表10.1所示。Java实用教程表表10.1 Java内嵌的许可类内嵌的许可类Java实用教程 建立这些类的对象就可以产生许可。例如,下面的代码用来产生许可读取/tmp

381、目录下名为Hello的文件: filePerm = new java.io.FilePermission(/tmp/Hello,read);Java实用教程10.3 安安 全全 策策 略略 (Policy) 1. keystore条目条目 keystore用来存放密钥对和相关数字证书。数字证书像X.509证书链用来鉴别相应的公有密钥。keytool工具用来创建和管理keystore。Policy配置文件中指定keystore,用来查找grant条目中签名者的公有密钥。如果存在指明签名的grant条目,那么必须存在相应的keystore。Keystore条目的格式为:keystore url,t

382、ypeJava实用教程 其中: (1) keystore是保留字,表示keystore条目。 (2) url指kestore的URL地址。 (3) type指keystore的类型,用于定义keystore信息的存储和数据格式,以及保护keystore中的私有密钥和keystore完整性算法。通常情况下缺省类型为“JKS”。Java实用教程 2. grant条目条目 policy对象中含有0到多条grant条目,指明远程代码访问特定资源的相关许可。grant条目的格式如下:grant signedBy name codeBase url Permission permission-class-

383、name target-name, action-name ; Permission permission-class-name target-name, action-name ;Java实用教程 其中: (1) 每个grant条目为由name签名且来源于codeBase的类的访问提供一系列许可permission-class-name。 (2) grant为保留字,表示一条授权。 (3) signedBy为保留字,指明签名者。 (4) name为数字签名的作者名。 (5) codeBase为保留字,指明代码来源。 (6) url为指定代码的来源路径。Java实用教程(7) Permissi

384、on为保留期,指明许可名字及许可操作。(8) permission-class-name指许可类名。(9) target-name为受保护资源的名字,如文件目录。(10) action-name 为对受保护资源进行操作的权限。Java实用教程 例如,下面为两条具体的grant条目,第一条表示允许lihua签名的网址http:/192.100.100.43:8080/下的访问代码对temp目录的所有文件有读、写权限。第二条表示对本机java.home目录的子目录/lib/ext/下的所有代码授予任意访问受保护资源的权限。grant signedBy lihua codeBase http:/19

385、2.100.100.43:8080/Permission java.io.FilePermission tmp/*,read,wirte;grant codeBase file:$java.home/lib/ext/* permission java.security.AllPermission;Java实用教程10.4 辅辅 助助 工工 具具10.4.1 密钥和证书管理工具密钥和证书管理工具 keytool为密钥和证书管理工具。它使得用户可以管理他们自己的公共密钥和私有密钥对以及相关的证书,用于在数字签名中进行数据完整性验证和身份验证。 keytool将密钥对和证书存放在keystore中,

386、keystore通常以文件的形式存在。创建keystore时需要为它设置密码,还要为其中的私有密钥设置密码。命令提示符状态下键入不带参数的命令keytool,可以看见它的用法,如图10.4所示。Java实用教程图10.4 keytool的用法Java实用教程 例如,在命令行提示符状态下键入如下命令行,生成UseImage.keystore文件,密钥和keystore的密码均为xueliang,显示结果如图10.5所示。keytool -genkey -alias UseImage -keypass xueliang -keystore UseImage.keystore -storepass

387、xueliang 其中: (1) -genkey:选项,表示生成新的密钥。 (2) -alias:别名选项,表示紧跟的参数为别名具体值:UseImage。Java实用教程 (3) -keypass:密钥的密码选项,表示紧跟的参数为密钥的密码具体值:xueliang。 (4) -keystore:选项,表示紧跟的参数为生成的keysotre文件名称:UseImage.keystore。 (5) -storepass:keystore密码的选项,表示紧跟的参数为keystore文件的密码具体值:xueliang。 Java实用教程图10.5 生成文件UseImage.keystoreJava实用教

388、程 而要将公共密钥导入证书,则需要键入如下代码,生成UseImage.cer证书文件,结果如图10.6所示。 keytool -export -alias UseImage -file UseImage.cer -keystore UseImage.keystore -storepass xueliang图10.6 生成证书文件UseImage.cerJava实用教程10.4.2 签名和校验工具签名和校验工具 jarsigner用来对JAR文件进行数字签名和校验,这个过程基于keytool生成的keystore。在命令提示符状态下键入jarsigner后按回车键,可以看见用法及选项说明,如图1

389、0.7所示。图10.7 jarsigner工具的用法及选项 Java实用教程 常用的签名格式为: jarsigner -keystore keysotre-file -storepass keystore-password jar-file alias 其中: (1) keystore-file为keytool生成的keystore文件。 (2) keystore-password为keystore的密码。 (3) jar-file文件为档案文件而且只能为档案文件。例如:jar cvf UseImage.jar UseImage.class index_01.gif;/生成JAR文件jarsi

390、gner -keystore UseImage.keystore -storepass xueliang UseImage.jar UseImage/进行签名Java实用教程10.4.3 PolicyTool Policytool是图形用户界面工具,可帮助用户指定、生成、编辑一个安全策略。命令提示符状态下键入PolicyTool后按回车键,就可调出此图形界面。根据界面指示,可以实现一个policy文件的各种操作。下面来看一下系统默认的policy文件,将D:j2sdk1.4.0_01jrelibsecurity目录下的java.policy文件拷贝到E:_WorkJavasample目录下,在

391、命令行状态运行命令policytool,弹出“规则工具”对话框。单击“文件”菜单中的“打开”项,选择java.policy文件并打开,如图10.8所示。从图10.8中可以看出允许两个CodeBase来源的远程代码。Java实用教程图10.8 使用policytool工具打开java.policy文件Java实用教程 选中第一个规则项目“CodeBase file:$java.home/lib/ext/*”,单击“编辑规则项目”按钮,弹出一个“规则项目”的窗口,如图10.9所示,可以看见签名项(SignedBy:)为空,而权限一栏中为 permission java.security.AllPe

392、rmission;表示允许这个规则项目下的所有远程代码对系统的所有资源进行访问。Java实用教程图10.9 全部授权的权限列表Java实用教程 选中第二个规则项目“CodeBase ”,单击“编辑规则项目”按钮,弹出如图10.10所示窗口。权限列表中可以看出对普通属性都有读的权限。这是客户端对所有远程代码的默认的安全限制列表。Java实用教程图10.10 所有远程代码访问的默认权限列表Java实用教程这个默认的java.policy文件对应的源文件如下:/ Standard extensions get all permissions by defaultgrant codeBase file

393、:$java.home/lib/ext/* permission java.security.AllPermission;/ default permissions granted to all domainsJava实用教程grant / Allows any thread to stop itself using the java.lang.Thread.stop() / method that takes no argument. / Note that this permission is granted by default only to remain / backwards co

394、mpatible. / It is strongly recommended that you either remove this permission / from this policy file or further restrict it to code sources / that you specify, because Thread.stop() is potentially unsafe.Java实用教程/ See http:/ for more information.permission java.lang.RuntimePermission stopThread;/ a

395、llows anyone to listen on un-privileged portspermission .SocketPermission localhost:1024-, listen;/ standard properies that can be read by anyonepermission java.util.PropertyPermission java.version, read;permission java.util.PropertyPermission java.vendor, read;permission java.util.PropertyPermissio

396、n java.vendor.url, read;Java实用教程permission java.util.PropertyPermission java.class.version, read;permission java.util.PropertyPermission os.name, read;permission java.util.PropertyPermission os.version, read;permission java.util.PropertyPermission os.arch, read;permission java.util.PropertyPermissio

397、n file.separator, read;permission java.util.PropertyPermission path.separator, read;permission java.util.PropertyPermission line.separator, read;Java实用教程permission java.util.PropertyPermission java.specification.version, read;permission java.util.PropertyPermission java.specification.vendor, read;pe

398、rmission java.util.PropertyPermission java.specification.name, read;permission java.util.PropertyPermission java.vm.specification.version, read;permission java.util.PropertyPermission java.vm.specification.vendor, read;permission java.util.PropertyPermission java.vm.specification.name, read;permissi

399、on java.util.PropertyPermission java.vm.version, read;permission java.util.PropertyPermission java.vm.vendor, read;permission java.util.PropertyPermission java.vm.name, read;Java实用教程10.5 签名及发布的例子签名及发布的例子10.5.1 步骤步骤 在命令提示符状态下进入路径D:Apache Tomcat 4.0webappsROOTuser,所有操作都在服务器路径下操作,也可以在普通路径下操作,完成后将一系列文件配

400、置到服务器端。本书作者使用前者,在user目录下建立AppletSecurity.java文件,源代码即为例10.1,编译后生成三个类:AppletSecurity.class、AppletSecurity$1.class和AppletSecurity$2.class。 (1) 将生成的类文件打包成文档文件。 jar cvf a.jar *.classJava实用教程 (2) 为刚才创建的文件创建keystore。 keytool -genkey -alias a -keypass xueliang -keystore a.keystore -storepass xueliang (3) 使用

401、刚才生成的钥匙来对jar文件进行签名。 jarsigner -keystore a.keystore -storepass xueliang a.jar a (4) 将公共钥匙导入到一个cer文件中。 keytool -export -alias a -file a.cer -keystore a.keystore -storepass xueliang Java实用教程 (5) 网页转换及修改。 嵌入类的index.html写成: Java实用教程 使用htmlConverter工具,将index.html转换成使用插件的文件。源文件如下: Java实用教程 !-Java实用教程10.5.2

402、 结果结果 通过IE访问index.html,在类加载过程中,弹出一个“Java安全警告”窗口,如图10.11所示。图10.11 证书的安全警告窗口Java实用教程 单击“授予该会话”按钮,则出现Applet界面,如图10.12所示,在文件名栏敲入E:a.txt,然后按回车键以显示文本内容,如图10.13所示。图10.12 载入的Applet界面 Java实用教程图10.13 显示的文本内容Java实用教程习习 题题 1. 编写Applet,在客户端建立一个文件,测试Applet的安全限制和许可访问类,要求文件路径为“D:Hello.txt”,并存入数据“你好,欢迎来到Java世界”。编写的界

403、面如图10.14所示,文件名中写入路径,文件内容中写入数据,单击“存储”按钮,将数据存入客户端文件,单击“打开”按钮,又可以显示内容,将可能出现的异常输出到文本区域内。 2. 使用PolicyTool工具建立一个new.policy文件,要求对网址http:/192.100.100.43:79端口下所有访问进行许可授权。 3. 为习题1的Applet加入数字签名,并进行访问。Java实用教程图10.14 用户界面Java实用教程第第1111章章 JavaJava网络技术网络技术( (一一) ) 11.1 TCP Sockets基础基础 11.2 UDP Sockets基础基础 11.3 网页显

404、示控件网页显示控件 习习 题题 Java实用教程11.1 TCP Sockets基础基础 Sockets是一个编程抽象概念,它是网络上与另一个应用程序通信连接的句柄。Sockets编程将用户代码与TCP/IP协议堆栈的底层实现隔离开,允许用户灵活地实现自己的编程。基于TCP协议的TCP Sockets需要四个方面的数据:(1) 本地系统的IP地址。(2) 本地应用程序正在使用的TCP端口号。(3) 通信的远程系统的IP地址。(4) 通信的远程系统响应的TCP端口号。Java实用教程 TCP Sockets的应用模型通常是客户/服务器模型,一个服务器在一个特定端口等待远程计算机请求资源,给予响应

405、。客户程序绑定到这个端口,建立一个可靠连接来用于通信。 面向连接的操作使用TCP协议,在这个模式下的Socket必须在发送数据之前与目的地的Socket取得一个连接。连接建立后,Socket就可以使用一个流接口:打开读写关闭。所有发送的信息都会在另一端以同样的顺序被接收。面向连接的操作比无连接的操作效率低,但是数据的安全性更高。由于Socket使用是双方的,所以在客户端和服务器端的使用稍有不同。 Java实用教程(1) 客户端请求Socket的步骤如下: 建立客户端Socket连接; 得到Socket的读和写的流; 利用流; 关闭流; 关闭Socket。 使用一个服务器端的Socket请求比使

406、用一个客户端Socket请求要麻烦一些。服务器并不是主动地建立连接。相反地,服务器被动地监听客户端的连接请示,然后给它们服务。Java实用教程(2) 服务器端Socket要完成以下的基本的步骤: 建立一个服务器Socket并开始监听; 使用accept()方法取得新的连接; 建立输入和输出流; 在已有的协议上产生会话; 关闭客户端流和Socket; 回到或者转到; 关闭服务器Socket。Java实用教程图11.1 面向连接的Socket协作流程图Java实用教程 例如,HTTP请求通过服务器的80端口实现,服务器端类似于Socket监听,端口号为80。如果客户端希望通过应用程序获得网页,只需

407、采用面向连接的Socket,请求80端口,获取网页数据。首先打开一个连接,请求主机为服务器网址,请求端口号为80,然后发送命令请求“GET / HTTP/1.0rnrn”,得到返回的网页。 Java实用教程11.1.1 InetAddress类类 InetAddress对象表示一个Internet主机地址。这个主机地址可以通过名字和IP地址来标识。名字即主机名,例如本机名字为snowing,为字符串类型;IP地址为192.100.100.43,为四字节的数字,书写形式为a.b.c.d。InetAddress类的几个常用方法如下: public static InetAddress getByN

408、ame(String host) throws UnknownHostException 通过名字可以得到主机的IP地址。Java实用教程public String getHostAddress() 返回IP地址的字符串格式。 public String getHostName() 返回IP地址的主机名。 public static InetAddress getLocalHost() throws UnknownHostException 以InetAddress类封装的格式返回本机地址。public String toString() 转换成字符串格式。Java实用教程 【例11.1】In

409、etAddress对象应用的测试。获取本机地址并转换成字符串输出,输出本地主机名和IP地址以及通过局域网内计算机的名字得到它的IP地址。程序源代码如下:/程序文件名FindHost.javaimport .*;public class FindHost public static void main(String args) tryJava实用教程InetAddress h = InetAddress.getLocalHost();System.out.println(toString(): + h.toString();System.out.println(getHostName(): +h

410、.getHostName();System.out.println(getHostAddress():+h.getHostAddress();h = InetAddress.getByName(engine);System.out.println(h.getHostName() +: + h.getHostAddress(); catch(UnknownHostException e) System.out.println(e.getMessage(); Java实用教程 编译后生成FindHost.class文件,运行后输出结果界面如图11.2所示。由图11.2可以看出本地主机名为snowi

411、ng,IP地址192.100.100.43;engine为局域网内另一台计算机的名字,可以得到它的IP地址为192.100.100.186。Java实用教程图11.2 程序结果输出界面Java实用教程11.1.2 Socket类类 Socket类用来实现客户端的Socket。常用的构造方法有以下三种: public Socket() 创建一个无连接的Socket。 public Socket(InetAddress address, int port) 创建流式Socket,将它连接到InetdAdress类指明的主机和port端口上。 public Socket(String host, i

412、nt port) 创建流式Socket并将它连接到特定host的特定port端口上。Java实用教程 【例11.2】 建立客户端程序,访问网址http:/,返回网址的首页写入文件xjtu.html。 1. 程序建立的步骤程序建立的步骤 (1) 建立到http:/且端口为80的Socket连接。Socket clientSocket = new Socket(, 80);Java实用教程 (2) 初始化字节流。连接建立后的数据传输通过数据输入输出流实现,写文件又通过文件输入输出流来实现。各种流对象的初始化如下:DataOutputStream outbound = new DataOutputS

413、tream(clientSocket.getOutputStream();DataInputStream inbound = new DataInputStream(clientSocket.getInputStream();InputStreamReader inS = new InputStreamReader(inbound);File f = new File(xjtu.html);FileOutputStream fOut = new FileOutputStream(f);PrintStream p = new PrintStream(fOut);Java实用教程(3) 发送请求。

414、outbound.writeBytes(GET / HTTP/1.0rnrn);(4) 返回数据后,循环写入文件。int c;while(c = inS.read() != -1)p.print(char)c);Java实用教程(5) 关闭流。inS.close();outbound.close(); inbound.close(); clientSocket.close();Java实用教程2. 程序源文件程序源文件/程序文件名ReadClient.javaimport java.io.*;import .*;public class ReadClient public static voi

415、d main(String args) try Java实用教程 /初始化Socket对象Socket clientSocket = new Socket(, 80);System.out.println(Client1: + clientSocket);/初始化流对象DataOutputStream outbound = new DataOutputStream( clientSocket.getOutputStream() );DataInputStream inbound = new DataInputStream( clientSocket.getInputStream() );Inp

416、utStreamReader inS = new InputStreamReader(inbound);File f = new File(xjtu.html);Java实用教程FileOutputStream fOut = new FileOutputStream(f); PrintStream p = new PrintStream(fOut);outbound.writeBytes(GET / HTTP/1.0rnrn);/写入文件int c;while(c = inS.read() != -1) p.print(char)c); /关闭流inS.close(); outbound.cl

417、ose(); inbound.close(); clientSocket.close(); Java实用教程 catch (UnknownHostException uhe) System.out.println(UnknownHostException: + uhe); catch (IOException ioe) System.err.println(IOException: + ioe); Java实用教程 3. 输出结果输出结果 图11.3为程序输出的xjtu.html,而图11.4为网址http:/的首页,可以看出程序输出的网页图形丢失,这是因为此处的数据输入输出流只实现文本的读取

418、,而并未考虑图形的处理。 Java实用教程图11.3 程序输出的xjtu.html Java实用教程图11.4 网址http:/的首页Java实用教程11.1.3 ServerSocket类类 ServerSocket类实现服务器Socket,服务器Socket等待从网络到达的请求,基于这些请求完成操作,然后返回相应的结果给请求者。ServerSocket类有一个重要的方法: public Socket accept() 用户监听并接收一个连接。 【例11.3】编写TCP通信程序,服务器端发送字符串到客户端。Java实用教程 1. 服务器端程序建立的步骤服务器端程序建立的步骤 (1) 创建服务

419、器Socket(端口82,限制5个连接)和接收客户连接的Socket。 serverSocket = new ServerSocket(82, 5); Socket clientSocket = new Socket(); (2) 等待客户端连接。 clientSocket = serverSocket.accept();Java实用教程(3) 初始化输入输出流。DataInputStream inbound = new DataInputStream( client.getInputStream();DataOutputStream outbound = new DataOutputStre

420、am( client.getOutputStream();Java实用教程 (4) 当接收到“hello”字符串时,输出字符串“http:/ buffer = new StringBuffer(http:/ inputLine;while (inputLine = inbound.readLine() != null) if ( inputLine.equals(hello) ) outbound.writeBytes(buffer.toString(); break; Java实用教程(5) 关闭流以及Socket。outbound.close(); inbound.close(); cli

421、entSocket.close();Java实用教程2. 服务器端程序源文件服务器端程序源文件/程序文件名SimpleWebServer.javaimport java.io.*;import .*;public class SimpleWebServer public static void main(String args) ServerSocket serverSocket = null; Socket clientSocket = null; int connects = 0; try Java实用教程/创建服务器Socket,端口82,限制5个连接 serverSocket = ne

422、w ServerSocket(82, 5); while (connects 5) /等待连接 clientSocket = serverSocket.accept(); /操作连接 ServiceClient(clientSocket); connects+; serverSocket.close(); Java实用教程 catch (IOException ioe) System.out.println(Error in SimpleWebServer: + ioe); public static void ServiceClient(Socket client) throws IOExc

423、eption DataInputStream inbound = null; DataOutputStream outbound = null; try /获取输入输出流 inbound = new DataInputStream( client.getInputStream();Java实用教程 outbound = new DataOutputStream( client.getOutputStream(); StringBuffer buffer = new StringBuffer(http:/ String inputLine; while (inputLine = inbound.

424、readLine() != null) /判断输入为hello时输出字符串 if ( inputLine.equals(hello) ) outbound.writeBytes(buffer.toString(); break; Java实用教程 finally /打印清除连接,关闭流及Socket System.out.println(Cleaning up connection: + client); outbound.close(); inbound.close(); client.close(); Java实用教程3. 客户端程序客户端程序/程序文件名为ReadClient.javai

425、mport java.io.*;import .*;public class ReadClient public static void main(String args) try /与服务器建立连接Java实用教程Socket clientSocket = new Socket(192.100.100.43,82);System.out.println(Client1: + clientSocket);/初始化流对象 DataOutputStream outbound = new DataOutputStream( clientSocket.getOutputStream() ); Data

426、InputStream inbound = new DataInputStream( clientSocket.getInputStream() ); InputStreamReader inS = new InputStreamReader(inbound); /发送数据outbound.writeBytes(hellorn);Java实用教程System.out.println(hello);outbound.flush();int c;while(c = inS.read() != -1) System.out.print(char)c); catch (UnknownHostExcep

427、tion uhe) System.out.println(UnknownHostException: + uhe); Java实用教程catch (IOException ioe) System.err.println(IOException: + ioe); finally /关闭流及clientSocket inS.close(); outbound.close(); inbound.close(); clientSocket.close(); Java实用教程 4. 通信结果输出通信结果输出 通信结果如图11.5所示。上面的部分为服务器端的输出,清除每次连接的Socket,下面的部分为客

428、户端显示,首先打印客户端Socket情况,然后打印发送的hello数据,最后输出从服务器端返回的字符串。Java实用教程图11.5 基于TCP的Socket通信结果输出界面Java实用教程11.2 UDP Sockets 基基 础础 数据报Socket是包发送服务的接收和发送点,它接收和发送的每个包都是单独访问和路由的。从一个机器发送到另一个机器的包可能有不同的路由,而且可能以任意顺序到达。数据报Socket构造函数有三个,分别如下:public DatagramSocket() 构建数据报Socket,绑定到本地主机上的任意端口。 public DatagramSocket(int port

429、) 构建一个数据报Socket,将它绑定到指定的port端口。Java实用教程 public DatagramSocket(int port, InetAddress laddr) 构建一个数据报Socket,绑定到指定的laddr本地地址和port端口。 数据报可以通过connect方法建立连接,也可以直接使用send方法发送数据,使用receive方法接收数据,方法如下: public void connect(InetAddress address, int port) 将建立的数据报Socket连接到远程地址address的port端口。 public void receive(Dat

430、agramPacket p) 接收数据报包p。 public void send(DatagramPacket p) 发送数据报包p。Java实用教程11.2.1 DatagramPacket类类 从TCP的例子程序可以看出TCP Socket发送的数据是流式数据,而UDP Socket发送的数据是分块的数据包,这就用到DatagramPacket类。数据报Socket传输数据前首先构造数据报包,然后传输这个数据报包。数据报包的构造函数如下: DatagramPacket(byte buf, int length) 构建数据报包,接收length长度的包并放入buf。 DatagramPack

431、et(byte buf, int length, InetAddress address, int port) 构建数据报包,发送length长度的包到address指定的主机的port端口。Java实用教程 【例11.4】客户端循环发送数据“Client:Hello”到服务器端,服务器端截取字符串Hello输出,并将源字符串返回给客户端。 1. 程序建立的步骤程序建立的步骤(1) 服务器端程序建立的步骤。建立数据报Socket。DatagramSocket mysock = new DatagramSocket(1719); 建立数据报包,准备接收。byte buf = new byte10

432、24;DatagramPacket p = new DatagramPacket(buf,buf.length);接收或者发送。mysock.receive(p);.mysock.send(p);Java实用教程(2) 客户端程序建立的步骤。 建立数据报Socket。DatagramSocket mysock = new DatagramSocket(); 建立数据报包,准备接收。DatagramPacket p = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1719); 接收或者发送。mysock.receive

433、(p);.mysock.send(p);Java实用教程2. 服务器端源程序服务器端源程序/程序文件名为DatagramServer.javaimport .*;public class DatagramServer extends Objectpublic static String ReadRAS(String str)int indexstart = str.indexOf(:);int indexend = str.indexOf(o);String Msg = Server: + Java实用教程str.substring(indexstart+1,indexend+1);retur

434、n Msg; public static void main(String args) try DatagramSocket mysock = new DatagramSocket(1719); byte buf = new byte1024; DatagramPacket p = new DatagramPacket(buf,buf.length); while(true) Java实用教程mysock.receive(p);System.out.println(RECEIVE:+ new String(p.getData().trim();System.out.println(ReadRA

435、S(new String(p.getData().toString();mysock.send(p);System.out.println(SEND:+ new String(p.getData().trim(); catch(Exception e) System.out.println(e.getMessage(); Java实用教程3. 客户端源程序客户端源程序/程序文件名为DatagramClient.javaimport .*;import java.io.*;public class DatagramClient extends Objectpublic static void m

436、ain(String args)tryJava实用教程DatagramSocket mysock = new DatagramSocket();byte buf = new byte1024;String sendData = new String(Client:Hello);buf = sendData.getBytes();DatagramPacket p = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1719);while(true)mysock.send(p);System.out.println(SEND

437、:+ new String(p.getData().trim();Java实用教程mysock.receive(p);System.out.println(GET:+ new String(p.getData().trim(); catch(Exception e) System.out.println(e.getMessage(); Java实用教程 4. 通信结果显示通信结果显示 如图11.6所示,上面的一部分为客户端,SEND标志发送数据“Client:Hello”,下面部分为服务器端,可以看见RECEIVE标志的接收到的字符串为客户端发送的数据,然后服务器端将接收到的数据进行截取,显示

438、Hello字符串,前面加了Server标志,最后将原数据返回,在客户端又显示GET标志的接收到的字符串。Java实用教程图11.6 数据报Socket通信结果输出界面Java实用教程11.2.2 音频采集、播放实例音频采集、播放实例 【例11.5】下面给出一个音频采集与播放实例,使用UDP Socket和多线程技术实现局域网内部的声音采集与传输。实例采用对等访问模式,使用时只需输入Java UDPTalk “对方服务器IP地址”,然后单击“通话”按钮即可,如图11.7所示。本例是Applet和应用程序共用的,如果通过Applet进行访问,需要获取SERVER_NAME参数,或者在程序内写成定值

439、。另外,还需为此Applet进行数字签名,否则无权在客户端的机器上进行音频采集。Java实用教程/程序文件名为TalkSelf.javaimport java.io.*;import java.applet.*;import java.applet.Applet;import java.awt.*;import java.awt.event.*;import javax.sound.sampled.*;import .*;public class TalkSelf extends Applet implements Runnable, ActionListenerJava实用教程private

440、 static String SERVER_NAME;/ = 192.100.100.42;private static int SRTPPort = 1734;private static int MAXBUFFER = 8192;final int bufSize = 16384;private static boolean PlayButton = false;/是否播放按钮private static boolean keepRunning = true;/控制循环private boolean bRun = false;/控制播放private Thread TalkThread;p

441、rivate static PlaybackAudio PlayAudio; /播放音频实例private static CaptureAudio CapAudio;/采集音频实例Button PlayBtn; /通话按钮Button CaptureBtn;/停止按钮Java实用教程/初始化界面public void init()PlayBtn = new Button(通话);PlayBtn.addActionListener(this);add(PlayBtn);CaptureBtn = new Button(停止);CaptureBtn.addActionListener(this);a

442、dd(CaptureBtn);Java实用教程/启动线程public void start()if(TalkThread = null)TalkThread = new Thread(this);TalkThread.start();/响应动作事件public void actionPerformed(ActionEvent evt) String btnCaption = evt.getActionCommand();if(btnCaption.equals(通话)Java实用教程PlayButton = true; if(btnCaption.equals(停止)PlayButton =

443、false;bRun = false;/实现run函数public void run()while(keepRunning)if(PlayButton & !bRun) Java实用教程trybRun = true;CapAudio = new CaptureAudio(SERVER_NAME, SRTPPort);CapAudio.start();PlayAudio = new PlaybackAudio(SRTPPort);PlayAudio.start();catch(Exception e)Java实用教程System.out.println(e.getMessage(); /音频播放

444、类class PlaybackAudio extends Thread implements Runnable SourceDataLine line; Thread thread; DatagramSocket s; /数据报SocketDatagramPacket p; /数据报包int RTPPort;/构造函数:取得接收端口Java实用教程PlaybackAudio(int RTPPort) this.RTPPort = RTPPort; public void start() thread = new Thread(this); thread.setName(PlaybackAudi

445、o); thread.start(); public void run() AudioFormat format =new Java实用教程AudioFormat(8000,16,2,true,true);/设置音频格式DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);/设置数据线try line = (SourceDataLine)AudioSystem.getLine(info);/获得源数据线信息 line.open(format, bufSize);/打开源数据线 catch (LineUnavail

446、ableException ex) return; Java实用教程 byte data = new byteMAXBUFFER; int numBytesRead = 0; line.start();/启动源数据线 try s = new DatagramSocket(RTPPort); catch (IOException e) return; while (thread != null) Java实用教程try p = new DatagramPacket(data, data.length);s.receive(p);/接收包numBytesRead = p.getLength();

447、line.write(p.getData(), 0, numBytesRead);/写入源数据线 catch(IOException e) break; Java实用教程 s.close();/关闭数据报Socket if (thread != null) line.drain(); line.stop(); line.close(); line = null; /音频采集类class CaptureAudio extends Thread implements Runnable Java实用教程 TargetDataLine line; Thread thread; DatagramSock

448、et s; DatagramPacket p; String SERVER_NAME; int RTPPort; /构造函数:取得远程服务器名和端口,用于发送数据 CaptureAudio(String SERVER_NAME, int RTPPort) this.SERVER_NAME = SERVER_NAME; this.RTPPort = RTPPort; public void start() Java实用教程thread = new Thread(this); thread.setName(CaptureAudio); thread.start(); public void run

449、() AudioFormat format =new AudioFormat(8000,16,2,true,true);/AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian) DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);Java实用教程 try line = (TargetDataLine)AudioSystem.getLine(info);/设置目标数据线

450、信息 line.open(format,line.getBufferSize(); /打开目标数据线 catch (Exception ex) return; byte data = new byteMAXBUFFER; int numBytesRead=0; line.start(); /启动目标数据线 try Java实用教程 /构造数据报Socket s = new DatagramSocket(); catch (Exception ex) return; while (thread != null) try numBytesRead = line.read(data, 0, MAXB

451、UFFER);/读取采集数据Java实用教程p = new DatagramPacket(data, numBytesRead, InetAddress.getByName(SERVER_NAME), RTPPort); s.send(p);/发送数据 catch (Exception ex) break; s.close(); line.stop(); line.close(); line = null; Java实用教程/主函数 public static void main(String args)SERVER_NAME = new String(args0);TalkSelf t =

452、new TalkSelf();Frame f = new Frame(); f.addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent evt)System.exit(0););Java实用教程t.init();f.setSize(300,300);f.add(Center, t);f.show();t.start();Java实用教程图11.7 简单的通话界面Java实用教程11.3 网页显示控件网页显示控件11.3.1 JEditorPane JEditorPane类是一个文本组件,通过实现相应的

453、EditorKit接口可以编辑一些特殊格式的内容。它的内容类型有三种: (1) text/plain:使用默认的DefaultEditorKit的扩展,处理普通文本。 (2) txt/html:使用javax.swing.text.html.HTMLEditorKit提供HTML3.2的帮助,用以处理HTML文本,针对HTML中存在的一些链接,进行点击时可以激活超链接事件。 (3) txt/rtf:使用javax.swing.text.rtf.RTFEditorKit实现对RTF格式文本的处理。Java实用教程 这里侧重于处理HTML文本的情况,JEditorPane类的构造函数和处理HTML

454、常用到的方法如下: public JEditorPane()构建一个空JeditorPane。public JEditorPane(String url) 构建一个基于URL声明的字符串的JEditorPane。 public JEditorPane(URL initialPage) 构建一个基于特定URL对象的JeditorPane。 public void addHyperlinkListener(HyperlinkListener listener) 添加一个超链接监听者,通知任何变化,例如选中一个链接并进入时。 Java实用教程public void setPage(String ur

455、l) 设置显示的URL页面。字符串url 表示页面的URL地址。public void setPage(URL page) 设置显示的URL对象代表的page页面。public void setText(String t) 设置指定t内容。 public void setEditable(boolean b)b为true时,可编辑;b为false时,不可编辑,但只有当b为false时,才可以响应超链接事件。 Java实用教程11.3.2 HyperlinkListener和和HyperlinkEvent HyperlinkListener是超链接事件监听者接口,继承于EventListener

456、接口,只有一个事件:超链接更新,当点击链接或者进入链接时引发。这个事件的方法为: public void hyperlinkUpdate(HyperlinkEvent e) 当更新一个超链接时调用此方法。 HyperlinkEvent是超链接事件,用于通知有关超文本链接的变化,它有两个常用方法,一个方法用来获得事件的类型,另一个方法是获得超链接指向的URL网址。 public HyperlinkEvent.EventType getEventType()Java实用教程表表11.1 超链接事件的三种类型超链接事件的三种类型public URL getURL()返回超链接指向的URL地址。Jav

457、a实用教程 【例11.6】使用JEditorPane显示网页,当单击其中的链接时能够给予响应。 1. 分析分析 (1) 创建JEditorPane对象。 JEditorPane jep = new JEditorPane(); (2) 设置可编辑属性为false。 jep.setEditable(false); (3) 添加超链接事件监听器。 jep.addHyperlinkListener(new LinkFollower(jep);Java实用教程 (4) 显示网页。 jep.setPage(str); (5) 链接更新事件的处理。public void hyperlinkUpdate(H

458、yperlinkEvent evt) if(evt.getEventType() = HyperlinkEvent.EventType.ACTIVATED)jep.setPage(evt.getURL();Java实用教程2. 源程序源程序/程序文件名为DisplayHtml.javaimport java.io.*;import .*;import javax.swing.*;import javax.swing.event.*;public class DisplayHtml /在新窗口显示网页public static void showNetPage(String str)Java实用

459、教程JEditorPane jep = new JEditorPane();jep.setEditable(false);jep.addHyperlinkListener(new LinkFollower(jep);tryjep.setPage(str);catch(IOException e)jep.setContentType(text/html);jep.setText(Could not load + str + );Java实用教程JScrollPane jscrollp = new JScrollPane(jep);JFrame f = new JFrame(西安交通大学主页);f

460、.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);f.setContentPane(jscrollp);f.setSize(600, 400);f.show(); public static void main(String args) String getURL = http:/;showNetPage(getURL); Java实用教程/类:新开的网页窗口响应链接点击事件class LinkFollower implements HyperlinkListener private JEditorPane jep; pub

461、lic LinkFollower(JEditorPane jep) this.jep = jep; /超链接更新事件的处理 public void hyperlinkUpdate(HyperlinkEvent evt) /判断是否是激活事件 if(evt.getEventType() = HyperlinkEvent.EventType.ACTIVATED) Java实用教程try /显示新的网址jep.setPage(evt.getURL();catch(Exception e)System.out.println(e.getMessage(); Java实用教程3. 结果分析结果分析图11

462、.8 JEditorPane显示的网页Java实用教程图11.9 响应链接后进入的网页Java实用教程习习 题题 1. 建立TCP Socket读取http:/网址的首页,将之存入文件h2.html并在IE中显示此文件。 2. 建立TCP Socket进行通信,服务器端向客户端传送日期数据。 3. 使用UDP Socket进行通信,服务器和客户相互传送日期数据。 4. 仔细学习本章音频操作的实例,修改其中的一些数据,如缓冲值或音频流初始化参数,看是否会影响到音频的质量。 5. 使用java.swing包中的高级控件显示http:/网址的首页。Java实用教程第12章 Java网络技术(二) 1

463、2.1 URL类类12.2 URLEncoder类类12.3 URLDecoder类类12.4 URLConnection类类12.5 HttpURLConnection类类12.6 新新IO包的包的Socket应用应用习习 题题 Java实用教程12.1 URL 类类 URL类代表统一资源定位符(Uniform Resource Locator),指向WWW上的资源,资源可以是一个文件或者一个目录,也可以是一个更加复杂的对象,如对数据库的查询或者搜索引擎的查询。通常,一个URL可以被拆分成几个部分,例如: http:/192.100.100.43:8080/web/index.html?se

464、arch=Java 其中: (1) http用来描述使用的协议为超文本链接协议。Java实用教程 (2) 192.100.100.43是信息存放的主机IP地址(也可以是主机名,如)。 (3) 端口号为8080,默认都为80端口。 (4) web/index.html为HTTP服务器上文件的虚拟路径。 (5) ?search=Java为网页上表单使用GET方法进行查询的附加部分,?表示后面跟的是提交的表单的名-值对,格式为“名=值”。search为查询词的名字,Java为查询词的值,即用户要查询的值,提交搜索引擎时可以有0个到多个这样的查询名-值对。Java实用教程 URL类用来定位WWW上的资

465、源,从而进行处理,如读取网页等。它的构造函数以及一系列常用的方法如下: public URL(String spec) 从指定的字符串spec创建一个URL对象。 public URL(String protocol, String host, int port, String file) 从指定的protocol协议、host主机、port端口号和file文件名创建一个URL对象。 public URL(String protocol, String host, String file) 从指定的protocol协议、主机名host和文件名file创建一个URL对象。Java实用教程publ

466、ic Object getContent() 得到URL的内容。public String getContentType()返回网页内容类型,普通网页为“text/html”。public String getFile() 得到URL文件名。public String getHost() 得到URL的主机名。public String getPath() 得到URL的路径部分。public int getPort()得到URL的端口号。Java实用教程public String getProtocol() 得到URL的协议名。public String getQuery() 得到URL的查询部

467、分。public URLConnection openConnection() 返回一个URLConnection对象,代表到URL远程对象的连接。 public InputStream openStream() 打开到URL的连接,返回读取连接的输入流。public String toExternalForm() 构建代表URL对象的字符串。 public String toString() 转换成字符串,覆盖来自对象的toString()方法。Java实用教程12.2 URLEncoder类类 URLEncoder类是一个工具类,用于HTML表单的编码。类只包含一个静态方法,这个方法将字符

468、串转换成application/x-www-form-urlencoded MIME格式。该方法如下: public static String encode(String s, String enc) throws UnsupportedEncodingException 使用指定的enc编码格式将字符串s转换为application/x-www-form-urlencoded格式,得以在网上传输。Java实用教程 其中: (1) s为要转换的字符串。 (2) enc是字符编码格式名称,包括US-ASCII、ISO-8859-1、UTF-8等。Java实用教程 【例12.1】将查询表单提交的

469、网址和相应的两个查询“名-值对”使用“UTF-8”编码格式进行编码。 1. 分析分析 (1) 在程序中定义了一个QueryString类,实现多个名-值对的编码和连接。其中一对名-值对编码如下: query = URLEncoder.encode(name.toString(),UTF-8) + = + URLEncoder.encode(value.toString(),UTF-8);Java实用教程 (2) 名-值对之间用符号&连接。if(!query.trim().equals()query += &; (3) 主函数中对QueryString类的引用。QueryString q = n

470、ew QueryString(cdtype,GB);q.add(word,Java);Java实用教程2. 源程序源程序/程序文件名UseEncode.javaimport .*;import java.io.*;public class UseEncode public static void main(String args) String fullURL = http:/ /新建QueryString对象,调用方法Java实用教程QueryString q = new QueryString(cdtype,GB);q.add(word,Java);fullURL += q.toStrin

471、g(); /打印编码后的字符串System.out.println(编码后的字符串: + fullURL);/类:处理请求串,编码成网页识别格式class QueryStringJava实用教程private String query; /构造函数,初始名值对的编码public QueryString(Object name, Object value)try query = URLEncoder.encode(name.toString(),UTF-8) + = + URLEncoder.encode(value.toString(),UTF-8); catch(UnsupportedEnc

472、odingException e) System.err.println(e);Java实用教程/构造函数public QueryString()query = ;/添加名值对,之间用符号&进行连接public synchronized void add(Object name, Object value)if(!query.trim().equals()query += &;tryquery += URLEncoder.encode(name.toString(),UTF-8) + = + URLEncoder.encode(value.toString(),UTF-8);Java实用教程c

473、atch(UnsupportedEncodingException e)System.err.println(e);/返回编码后的字符串public String toString()return query;/清空public void clear()query = ;Java实用教程 3. 结果输出结果输出 图12.1为搜索引擎提交的查询字符串编码的结果。可以看见提交网址的?后跟了两个名值对,cdtype=GB 和word=Java,它们之间用符号&隔开。 图12.1 编码后字符串输出结果Java实用教程12.3 URLDecoder类类 URLDecoder类是URLEncoder类的解

474、码类。它的构造函数和解码方法如下: public URLEncoder() public static String decode(String s, String enc) 使用编码格式enc对application/x-www-form-urlencoded字符串s进行解码。Java实用教程12.4 URLConnection类类 抽象类URLConnection代表应用程序和URL之间通信连接的类的超类。类的实例可以用来读取和写入URL代表的资源。URLConnection类实现的两个方法如表12.1所示。表12.1 URLConnection类实现的两个方法Java实用教程上述两个方法

475、的实现步骤如下:(1) 调用openConnection方法建立连接对象。(2) 操作建立参数和普通请求参数。(3) 调用connect方法建立到远程对象的实际连接。(4) 远程对象可用,头文件和远程对象的内容可以访问。Java实用教程 【例12.2】编写程序,访问天网主页(http:/)并查询Java一词,将查询结果存入result.html文件。1. 分析分析(1) 建立URL对象。u = new URL(fullURL);(2) 打开到URL对象的连接。conn = u.openConnection();(3) 获取输入流。theData =conn.getInputStream();(

476、4) 输出到文件。p.println(line);Java实用教程2. 源程序源程序/程序文件名Search.javaimport .*;import java.io.*;public class Search public static void main(String args) String fullURL = http:/ conn = null;Java实用教程 OutputStream theControl =null; InputStream theData =null; URL u=null; /建立URL对象,参数为请求地址+编码后的请求串 try fullURL += UR

477、LEncoder.encode(cdtype,UTF-8) + = + URLEncoder.encode(GB,UTF-8);fullURL += & + URLEncoder.encode(word,UTF-8) + = + URLEncoder.encode(Java,UTF-8);u = new URL(fullURL);Java实用教程catch(UnsupportedEncodingException e)System.err.println(e);catch(MalformedURLException e) System.err.println(网页错误:+fullURL+e);

478、System.exit(1);/打开连接,读入网页流数据try conn = u.openConnection();theData =conn.getInputStream(); /得到网页类型:text/htmlJava实用教程String contentType=conn.getContentType(); /建立文件对象和读取的流对象File f = new File(result.html);FileOutputStream fOut = new FileOutputStream(f);PrintWriter p = new PrintWriter(fOut);if(contentTy

479、pe.toLowerCase().startsWith(text) BufferedReader in = new BufferedReader(new InputStreamReader(theData);String line;while (line = in.readLine()!=null) Java实用教程/输出到文件p.println(line);else System.out.println(程序只处理文本响应);System.out.println(得到的类型为:+contentType); catch(IOException e) System.err.println(e);

480、System.exit(2); Java实用教程 3. 结果分析结果分析 程序运行结果如图12.2所示,左部分为浏览器中天网检索的结果,右部分为程序检索结果result.html,由于没有考虑图片的读取,可以看出程序输出缺少所有的图片,但是文本字符和检索结果都是一致的。Java实用教程图12.2 程序检索结果和天网检索结果的对比Java实用教程12.5 HttpURLConnection类类 HttpURLConnection类继承URLConnection类,专门支持HTTP协议相关的特征。每个HttpURLConnection实例完成一个单一的请求,其构造函数如下: protected H

481、ttpURLConnection(URL u) 构建一个到URL对象u代表的网络资源的HttpURLConnection连接。 public int getResponseCode() throws IOExceptionJava实用教程 返回HTTP状态码,如: HTTP/1.0 200 OK HTTP/1.0 401 Unauthorized HttpURLConnection类中有一系列的常量值对应着这些状态码。例如HTTP_OK对应着上面列出的第一个状态码,而HTTP_UNAUTHORIZED对应着第二个状态码。Java实用教程 【例12.3】返回网址的首页,并与从浏览器获得的网页进行

482、比较。/程序文件名为UseHttp.javaimport java.io.*;import .*;public class UseHttppublic static void main(String args)String urlstring = http:/;String httpresp = new String();String status = new String(good);tryJava实用教程/构造URL对象URL currenturl = new URL(urlstring);urlstring = currenturl.toString(); /判断是否是HTTP协议if(

483、!currenturl.getProtocol().equals(http)status = currenturl.getProtocol() + protocol;else /打开连接 URLConnection conn = currenturl.openConnection(); /建立HttpURLConnection对象Java实用教程HttpURLConnection httpconn = (HttpURLConnection)conn; /判断是否正确返回if(httpconn.getResponseCode() = HttpURLConnection.HTTP_OK)if(ht

484、tpconn.getContentType().equals(text/html) /构造文件读写流对象,写入文件InputStreamReader isr = new InputStreamReader(conn.getInputStream();File f = new File(sohu.html);FileOutputStream fOut = new FileOutputStream(f);PrintWriter p = new PrintWriter(fOut);Java实用教程int c;while(c = isr.read() != -1)p.write(c);isr.clos

485、e();httpconn.disconnect();elsestatus = Not text/html;elsestatus = bad; Java实用教程catch(Exception e)status = e.toString();System.out.println(Exception: + e.getMessage();if(status.equals(good)System.out.println(urlstring);elseSystem.out.println(status);System.out.println(Bad URL = + urlstring); Java实用教程

486、 由图12.3可以看出,左边的页面是网址首页,右边的网页是程序生成的sohu.html页面。比较可得,两个页面是一致的。可以看出随着类的依次封装,可应用领域变窄(从Socket到URL,再到针对HTTP协议的URL),但相对专门的应用而言,用户使用起来更为简单。Java实用教程图12.3 程序输出页面和网址首页的比较Java实用教程12.6 新新IO包的包的Socket应用应用 在J2sdk1.4中提供了一个新I/O包(java.nio),通过引入四个基本抽象类,开发网络Socket连接的非阻塞应用。对于第11章Java编程中的多个Socket连接,用线程实现时会遇到一些问题,如操作系统限制、

487、死锁、线程安全违反等。而新I/O提供的特性可以很好地解决这些问题。引入的四个基本抽象类如下:Buffer:包含读写的数据线性流。Charset:将Unicode字符与字节流之间进行相互转换。Channels:可以是Socket、文件或管道,代表双边通信的管道。Selectors:多元异步I/O操作,应用于单个线程或多个线程。Java实用教程12.6.1 Buffers Buffer是一个线性、有序的数据集,提供了一种在内存容器中保存一系列原始数据的机制。Buffer进行特定的封装之后只允许读写一种数据类型,例如char、int或double等。共有七种读写不同数据类型的Buffer,如表12.

488、2所示。表12.2 读写不同数据类型的BufferJava实用教程 Buffer中涉及到的四个基本概念是capacity(容量)、position(位置)、limit(限制)和mark(标记)。 capacityBuffer的大小(=size); position在Buffer中目前读写的位置(=limit); limit第一个不应该被读取元素的位置的index(索引号)(=capacity); mark 用mark方法设置的可设位置,mark方法可以使用reset来重置position(=0)。Java实用教程 【例12.4】下面给出一段缓冲操作的代码,依次演示capacity、positi

489、on和limit的值,代码段为:ByteBuffer buf = ByteBuffer.allocateDirect(8);buf.put( (byte)0xca );buf.putShort( (short)0xfeba );buf.put( (byte)0xbe );buf.flip();Java实用教程 代码段分析如下: ByteBuffer buf = ByteBuffer.allocateDirect(8); 分配8字节的字节缓冲,position=0、capacity=8、limit=8,如图12.4(a)所示。 buf.put( (byte)0xca ); buf.putShor

490、t( (short)0xfeba ); buf.put( (byte)0xbe ); 依次放入三个数据,两个字节数据和一个短整型数据,其中短整型数据占两个字节,position=4、capacity=8,如图12.4(b)所示。 buf.flip();Java实用教程 上面这行语句是填充数据之后、写入通道之前需要调用的方法,将position重定位到0,将limit定位到数据结束位置,准备好序列写入通道。position=0、capacity=8、limit=4,如图12.4(c)所示。Java实用教程图12.4 缓冲的变化过程显示Java实用教程12.6.2 Charset Charset(

491、字符集)定义了Unicode和字节之间的映射。字符集根据IANA标准定义,Java中字符集由java.nio.charset.Charset实例代表,使用Charset.forName()得到合适实例。Charset.availableCharsets()给出支持字符集名的映射和它们的Charset实例。JDK1.4包括8个字符集:US-ASCII、ISO-8859-1、ISO-8859-15、UTF-8、UTF-16等。Charset构造CharsetEncoder和CharsetDecoder,使得有序字符和字节之间可以进行转换,输出时使用encoder,对输入请求使用decoder。以下

492、代码段是对字符buffer进行编码的情况。Java实用教程Charset charset = Charset.forName(UTF-8);/ISO-8859-1US-ASCIIByteBuffer buffer = charset.newEncoder().encode(chars);ByteBuffer directBuffer = ByteBuffer.allocateDirect(buffer.limit();directBuffer.put(buffer);Java实用教程12.6.3 Channels 1. ServerSocketChannel Java.nio.channels

493、.ServerSocketChannel与.ServerSocket一样,用于创建一个监听线程来接收到来的连接,只是既不能读也不能写。ServerSocketChannel.socket()提供对底层ServerSocket的访问,因此可以设置Socket选项。这个通道可以使用ServerSocketChannel.open()工厂方法创建。ServerSocketChannelaccept()为新建立连接的客户返回java.nio.channel.SocketChannel。如果ServerSocketChannel进入阻塞模式,accept()不会返回,直到一个有连接请求到达;而在非阻塞模

494、式,不管Socket是否为空,总是立刻返回。Java实用教程 2. SocketChannel Java.nio.channels.SocketChannel在应用程序中封装了.Socket并添加非阻塞模式和状态机。SocketChannel可以通过两种方法创建:SocketChannel.open()创建一个新的、无连接的SocketChannel;通过ServerSocketChannel.accept()返回的Socket,实际上有一个开放和连接的SocketChannel附加在它上面。 Java实用教程 3. FileChannel 文件通道允许使用操作系统的文件缓冲直接进行文件传输。

495、文件通道可以将文件区域映射到内存。 MappedByteBuffer是一个专门用于直接缓冲的ByteBuffer,这个类用字节缓冲来映射一个文件。想要映射一个文件到MappedByteBuffer,必须先取得这个文件的通道(channel)。通道是某种已建立的连接,如管道(Pipe)、套接口(Socket)或文件(File)等能够完成I/O操作的对象。Java实用教程 如果是文件通道,你可以通过FileInputStream(文件输入流)、FileOutputStream(文件输出流)或RandomAccessFile(随机存取文件)的getChannel方法来获得一个通道。一旦你取得这个通道

496、,就可以通过它的map方法指明映射模式,来把你想映射的那一部分文件映射到缓冲中去。文件通道可以使用FileChannel.MapMode的任一个常数打开:只读(READ_ONLY)、私有/写时拷贝(PRIVATE)或读写(READ_WRITE)。Java实用教程 【例12.5】使用文件通道打开一个文件并输出文件内容。 1. 分析分析 (1) 通过文件输入流对象得到通道。FileInputStream input = new FileInputStream(filename);FileChannel channel = input.getChannel(); (2) 映射到字节缓冲。 int f

497、ileLength = (int)channel.size(); MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);Java实用教程(3) 字符集进行解码。Charset charset = Charset.forName(ISO-8859-1);/CharsetDecoder decoder = charset.newDecoder();CharBuffer charBuffer = decoder.decode(buffer);(4) 输出文件内容。System.out.p

498、rintln(charBuffer);Java实用教程2. 源程序源程序/程序文件名为UseFchannel.javaimport java.io.*;import java.nio.*;import java.nio.channels.*;import java.nio.charset.*;class UseFchannel public static void main(String args) tryJava实用教程String filename = f.txt;FileInputStream input = new FileInputStream(filename);FileChann

499、el channel = input.getChannel();int fileLength = (int)channel.size();MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);Charset charset = Charset.forName(ISO-8859-1);/CharsetDecoder decoder = charset.newDecoder();CharBuffer charBuffer = decoder.decode(buffer);System.

500、out.println(charBuffer);Java实用教程catch(Exception e)System.out.println(Error: + e.getMessage(); Java实用教程 3. 结果分析结果分析 图12.5上一部分显示打开的文件内容,下一部分显示程序输出的内容,可以看出两者是一致的。图12.5 源文件内容与程序输出的内容对比Java实用教程12.6.4 Selectors 非阻塞I/O围绕为多元选择通道准备的Selectors(选择器)对象构建。选择器对象保持一系列选择键,这些键在应用中可由某个事件激活。选择器本身管理键,编程人员使用键的状态管理回调来完成客户

501、请求。构造函数如下:protected Selector()初始化一个实例。选择器可以通过调用自带的open方法进行创建:Selector s Selector.open();Java实用教程 下面的两个方法用来返回选择键值的个数和键值集合。 public abstract int select() throws IOException 返回键值的个数。 public abstract Set selectedKeys() 返回选择器选中的键值集合。 对于一个Socket通道,只有将它本身发生的事件(如监听、连接、读、写等)在选择器上进行注册,才可以被选择器识别,从而进行处理,这个注册就用到S

502、electionKey类。SelectionKey类包括四个注册值,将通道支持的事件注册到相应的选择器上。它还提供四个判断键值状态的方法,从而进行相应的事件处理,如表12.3所示。Java实用教程表表12.3 SelectionKey类的注册值及其方法类的注册值及其方法Java实用教程例如,接收新连接的通道应该注册为:ServerSocketChannel ch = ServerSocketChannel.open();SelectionKey acceptKey = ch.register(s,SelectionKey.OP_ACCEPT);一个读取和写入数据的通道应该注册为:Selecti

503、onKey readWriteKey = ch.register(s,SelectionKey.OP_READ|SelectionKey.OP_WRITE);当用户发送一个请求时,选择器通过返回键进行工作。/循环实现While(keysAdded = s.select()0)Java实用教程 /返回键值集合set readyKeys = s.selectedKeys();/使用Iterator枚举Iterator I = readKeys.iterator();While(i.hasNext()SelectionKey sk = (SelectionKey)i.next();.接收连接处理请求

504、;Java实用教程 具体的处理可以根据键值的状态进行,上面的“接收连接处理请求”就可以为:i.remove();if ( key.isAcceptable() ) .else if ( key.isWritable() ) .Java实用教程12.6.5 阻塞模式阻塞模式 在阻塞模式下,服务器端和客户端的程序基本相同,惟一不同的是客户端为Connect方法,服务器端为Accept方法。 新I/O包处理Socket的读写操作时使用包中的InetSocketAddress类指定链接地址,并用前面介绍的SocketChannel类来完成实际的读写操作。InetSocketAddress类提供一个用来

505、绑定、连接或者返回数值的远程对象。它常用的构造函数为: InetSocketAddress(String hostname, int port) 以名字hostname和端口号port创建socket地址。Java实用教程 客户端使用SocketChannel建立连接的步骤如下: (1) 首先获得InetSocketAddress的对象。 String host = ; InetSocketAddress socketAddress = new InetSocketAddress(host, 80); (2) 打开一个到InetSocketAddress代表的主机的连接。 使用SocketCh

506、annel取代以前从Socket对象的输入流来读取、向Socket的输出流写入的所有操作: SocketChannel channel = SocketChannel.open(); channel.connect(socketAddress);Java实用教程(3) 发送一个HTTP请求,发送请求之前进行编码。Charset charset = Charset.forName(ISO-8859-1);CharsetEncoder encoder = charset.newEncoder();String request = GET / HTTP/1.0rnrn ;channel.write(

507、encoder.encode(CharBuffer.wrap(request);Java实用教程(4) 从通道中读取服务器的响应。ByteBuffer buffer = ByteBuffer.allocateDirect(1024);CharBuffer charBuffer = CharBuffer.allocate(1024);while (channel.read(buffer) != -1) buffer.flip(); decoder.decode(buffer, charBuffer, false); charBuffer.flip(); System.out.println(ch

508、arBuffer); buffer.clear(); charBuffer.clear();Java实用教程 【例12.6】下面这个程序通过一个HTTP请求来读取站点的首页,直接输出到屏幕上,可以看见是网页的文本文件。源程序代码如下:/程序文件名为ReadURL.javaimport java.io.*;import .*;import java.nio.*;import java.nio.channels.*;import java.nio.charset.*; Java实用教程public class ReadURLpublic static void main(String args)

509、SocketChannel channel = null;String host = ;try /建立连接InetSocketAddress socketAddress = new InetSocketAddress(host, 80);Java实用教程Charset charset = Charset.forName(ISO-8859-1);CharsetDecoder decoder = charset.newDecoder();CharsetEncoder encoder = charset.newEncoder();/分配缓冲ByteBuffer buffer = ByteBuffer

510、.allocateDirect(1024);CharBuffer charBuffer = CharBuffer.allocate(1024);/连接channel = SocketChannel.open();channel.connect(socketAddress);/发送请求String request = GET / HTTP/1.0rnrn;channel.write(encoder.encode(CharBuffer.wrap(request);while (channel.read(buffer) != -1) Java实用教程 buffer.flip();/解码decoder

511、.decode(buffer, charBuffer, false);/输出charBuffer.flip();System.out.println(charBuffer);buffer.clear();charBuffer.clear(); catch (UnknownHostException e) System.err.println(e); catch (IOException e) System.err.println(e);Java实用教程 finally if (channel != null) try channel.close(); catch (IOException ig

512、nored) Java实用教程12.6.6 非阻塞模式非阻塞模式 1. 非阻塞客户端非阻塞客户端 (1) 创建可选择通道,配置成非阻塞模式并进行连接。 String host = 192.100.100.43; InetSocketAddress socketAddress = new InetSocketAddress(host, 80); channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(socketAddress); 这时得到的通道channel是一个可选择通道(Select

513、ableChannel),通过一个Selector来工作。将通道注册到一个Selector,同时声明一些事件,当事件发生时通道会通过回调执行。Java实用教程 (2) 创建Selector实例。 Selector selector = Selector.open(); (3) 通道向选择器的注册。对于SocketChannel类来说,有效的操作事件是OP_CONNECT、OP_READ 和 OP_WRITE,因此可以进行如下注册: channel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);Java实用教

514、程 (4) 处理通道事件。当有事件在通道上发生时,Selector进行通知,然后使用一个while (selector.select() 0)循环进行处理。发出请求后得到响应的代码都放入这一段,当作读写事件进行处理。 (5) 加入异常处理代码。加入必要的try.catch(Exception e).语句,并在finally代码段中加入关闭通道的代码。Java实用教程 【例12.7】下面是完整的例子程序,结果是得到本机tomcat主页并显示在标准输出上。用户也可以将它输出到文件中,以方便与原网页进行比较。源程序代码如下:/程序文件名为NBReadURL.javaimport java.io.*;

515、import .*;import java.nio.*;import java.util.*;import java.nio.channels.*;import java.nio.charset.*;Java实用教程public class NBReadURLstatic Selector sele; public static void main(String args)String host = 192.100.100.43;SocketChannel channel = null;tryJava实用教程/初始化InetSocketAddress sockAddr = new InetSo

516、cketAddress(host, 8080);Charset charset = Charset.forName(ISO-8859-1);CharsetDecoder decoder = charset.newDecoder();CharsetEncoder encoder = charset.newEncoder();/分配缓冲ByteBuffer buf = ByteBuffer.allocateDirect(1024);CharBuffer cbuf = CharBuffer.allocate(1024);/连接channel = SocketChannel.open();channe

517、l.configureBlocking(false);channel.connect(sockAddr);Java实用教程/打开选择器sele = Selector.open(); channel.register(sele, SelectionKey.OP_CONNECT|SelectionKey.OP_READ); /Wait for something of interest to happen while(sele.select(500)0) /得到对象Set readyKeys = sele.selectedKeys();Iterator readyItor = readyKeys.

518、iterator();Java实用教程/遍历对象集while(readyItor.hasNext()/得到键SelectionKey k = (SelectionKey)readyItor.next();/Remove current entryreadyItor.remove();/得到通道SocketChannel keyChannel = (SocketChannel)k.channel();if(k.isConnectable()Java实用教程/完成连接if(keyChannel.isConnectionPending() keyChannel.finishConnect();/发送

519、请求String request = GET /index.html rnrn;keyChannel.write(encoder.encode(CharBuffer.wrap(request);else if(k.isReadable()Java实用教程/读取数据keyChannel.read(buf);buf.flip();/解码decoder.decode(buf, cbuf, false);/显示cbuf.flip();System.out.print(cbuf);/清除缓冲buf.clear();cbuf.clear();elseJava实用教程System.err.println(O

520、oops);catch(UnknownHostException e)System.err.println(e);catch(IOException e)System.err.println(e);finallyif(channel != null)Java实用教程trychannel.close();catch(IOException ignored)System.out.println();Java实用教程 2. 非阻塞服务器非阻塞服务器 使用新I/O包实现的非阻塞Web服务器,不必为每个连接都提供一个线程就可以实现Web服务器的功能。非阻塞服务器程序编写的步骤如下: (1) 创建接收通道

521、,配置非阻塞模式并绑定到InetSocketAddress对象。ServerSocketChannel channel = ServerSocketChannel.open();channel.configureBlocking(false);InetSocketAddress isa = new InetSocketAddress(port);channel.socket().bind(isa); Java实用教程 (2) 创建Selector实例。 Selector selector = Selector.open(); (3) 注册事件。服务器端需要注册的是OP_ACCEPT键值: ch

522、annel.register(selector, SelectionKey.OP_ACCEPT); (4) 处理通道事件。当有事件在通道上发生时,Selector进行通知,然后使用一个while (selector.select() 0)循环进行处理。发出请求得到响应的代码都放入这一段,当作读写事件进行处理。Java实用教程 (5) 添加异常处理代码。加入必要的try.catch(Exception e).语句,并在finally代码段中加入关闭通道的代码。 可以看出非阻塞模式下服务器和客户端编程的步骤都是一致的,只是有些步骤下编写的代码有所不同。Java实用教程 【例12.8】给出一个基本的

523、单线程的服务器,对每一个响应都发回一段文字信息来表示时间。源程序代码如下:/程序文件名为Server.javaimport java.io.*;import .*;import java.nio.*;import java.nio.channels.*;import java.util.*;public class Server Java实用教程private static int port = 4321;public static void main(String args) throws Exception Selector selector = Selector.open();Serve

524、rSocketChannel channel = ServerSocketChannel.open();channel.configureBlocking(false);InetSocketAddress isa = new InetSocketAddress(port);channel.socket().bind(isa);/注册channel.register(selector, SelectionKey.OP_ACCEPT);while (selector.select() 0) Java实用教程Set readyKeys = selector.selectedKeys();Iterat

525、or readyItor = readyKeys.iterator();while (readyItor.hasNext() SelectionKey key = (SelectionKey)readyItor.next();readyItor.remove();ServerSocketChannel keyChannel = (ServerSocketChannel)key.channel();ServerSocket serverSocket = keyChannel.socket();Socket socket = serverSocket.accept();/返回时间Java实用教程

526、PrintWriter out = new PrintWriter(socket.getOutputStream(), true); Date now = new Date();out.println(Hello, now time is: + now);out.close(); /End of While/End of While /End of mainJava实用教程 为了服务器与客户端能够进行通信,对例12.7的客户端程序进行修改,将InetSocketAddress对象sockAddr中的端口号改成4321,使得客户端请求的端口号与此服务器监听的端口号一致,即将InetSocketA

527、ddress sockAddr = new InetSocketAddress(host, 8080);改为InetSocketAddress sockAddr = new InetSocketAddress(host, 4321);然后重新编译,生成类文件。 启动两个命令提示符,其中一个为运行命令“java Server”,另一个为键入命令“java NBReadURL”,可以看见如图12.6的通信结果。客户端显示服务器发送的一段时间信息。如果希望在服务器端显示内容,还需修改服务器程序,注册服务器通道的读、写事件。Java实用教程图12.6 非阻塞模式下的通信输出Java实用教程习习 题题1

528、. 给出字符串,熟悉URLEncoder和URLDecoder类的规范。2. 从天网主页http:/检索包含“网络”一词的文件。3. 使用HttpURLConnection对象打开网页并输出到文件中。4. 使用文件通道将例12.6的程序输出改成输出到文件中。5. 编写非阻塞模式下的Socket通信。Java实用教程第13章 Servlet技术 13.1 Servlet概述概述13.2 Servlet生命周期生命周期13.3 使用使用Servlet 13.4 Applet与与Servlet通信通信习习 题题 Java实用教程13.1 Servlet 概概 述述 Servlet是用Java编写的且

529、协议和平台都独立的服务器端的组件。与客户端组件Applet相对应。Servlet扩展了面向请求/响应的服务器的模块,使用平台专用的API进行服务器端的编程。Servlet为服务器和基于Web的客户之间的通信提供了一条更为简单的途径。它的特殊用途包括: (1) 允许用户之间的合作。一个Servlet可以同时并发处理大量的请求,而且可以同步请求,因此使Servlets能够支持像在线会议这样的系统。Servlets能够并发地服务多个客户。Java实用教程 (2) 转发请求。Servlets能够转发请求到其它的服务器和Servlets,因此Servlets能够被用来在多个镜像同一个内容的服务器之间来平

530、衡负载,在多个服务器上根据任务类型或者组织边界分割单一的逻辑服务。Java实用教程13.2 Servlet生命周期生命周期图13.1 Servlet的生命周期Java实用教程 1. 初始化初始化Servlet 当服务器载入一个Servlet时,服务器运行Servlet的init方法。初始化在客户请求被处理和Servlet被销毁之前完成。Java实用教程 2. Servlet_Client交互交互 初始化成功后,HTTP Servlet调用Service方法处理客户请求,Service方法将每个请求分配到处理这个请求的方法,从而支持标准的HTTP客户请求。HttpServlet类中的方法处理客户

531、请求时使用以下两个参数: (1) HttpServletRequest对象:封装了从客户来的数据,主要提供了访问初始请求数据的方法和字段;访问客户数据时使用getParameter方法得到一个已命名参数的值。 (2) HttpServletResponse对象:封装了对客户的响应。使用getWriter方法返回文本数据给客户(可以以HTML网页的形式表现出来)。Java实用教程Service方法支配的HTTP请求如表13.1所示。表表13.1 Service方法支配的方法支配的HTTP请求请求Java实用教程 通常,编写的Servlet应该重载处理它支持的HTTP交互的方法。如果出错,这些方法

532、返回一个BAD_REQUEST(400)错误。当Servlet收到OPTIONS请求时,HttpServlet的Service方法调用doOptions方法。默认的doOptions的实现自动地决定了支持何种HTTP选项和返回信息。HTTP Servlets通常能够并发地服务多个客户。如果Servlet中的这个方法对于客户访问共享资源是可行的,那么你可以通过创建在某一时刻只能处理一个客户请求的Servlet来处理并发。Java实用教程 3. 销毁销毁Servlet Servlet一直运行直到服务器销毁它们,比如在系统管理员的要求下。当一个服务器销毁一个Servlet时,服务器运行Servlet

533、的Destroy()方法。方法只运行一次,服务器将不再运行Servlet,直到服务器重新载入和重新初始化Servlet。Java实用教程13.3 使用使用Servlet13.3.1 编写编写Servlet 【例13.1】 在客户端填写“用户注册信息”网页,并将此网页提交到后台服务器端Servlet,服务器端Servlet程序给予响应,并以网页的形式按行输出用户提交的基本信息。 1. 客户端客户端 客户端是一个“用户注册信息”的HTML网页,如图13.2所示。用户输入个人信息,点击“确定”按钮,将表单数据提交到服务器,然后等待服务器的响应。Index.html源文件代码如下:Java实用教程用户

534、注册信息收集用户注册信息Java实用教程 姓名: 身份证号: 性别男女Java实用教程职业 计算机业 医生 教师 军队 个性化宣言 Java实用教程 Java实用教程图13.2 “用户注册信息”网页Java实用教程 在网页index.html中要注意表单的书写,表单的action属性对应服务器端的Servlet,本例中取值为http:/192.100.100.43:8080/examples/Servlet/user.UserServlet;method属性是访问方法,本例中为POST方法。表13.2是表单中的元素标签和命名,可以看到除去“确定”和“清空”,其它的元素标签在第三栏都有一个对应的

535、名字,Servlet通过这些名字获得用户在界面上输入的值,而用户单击“确定”按钮时,表单内容就提交到action属性指定的Servlet。Java实用教程表表13.2 表单元素标签及命名表单元素标签及命名Java实用教程 2. 服务器端服务器端 服务器端Servlet收集用户界面输入的数据(见图13.3),然后按行返回这些内容,结果如图13.4所示。注意传输过程中中文字符可能会有出错情况,因此再添加一个转换字段,使得Servlet能够正确打印输出。/程序文件名:UserServlet.javapackage user;import java.io.*;import javax.Servlet.

536、*;import javax.Servlet.http.*;public class UserServlet extends HttpServlet Java实用教程String name,number,sex,job,ta;public void init() throws ServletExceptionsuper.init();name = new String();number = new String();sex = new String();job = new String();ta = new String();/解决中文转换问题public String parseChines

537、e(String inStr) Java实用教程String s = null; byte temp; if (inStr = null) /System.out.println(Warn:Chinese null founded!); return new String(); try temp=inStr.getBytes(iso-8859-1); s = new String(temp); catch(UnsupportedEncodingException e) Java实用教程System.out.println (e.toString(); return s; public void

538、 doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException /获取用户界面输入的值name = req.getParameter(name);number = req.getParameter(number);sex = req.getParameter(sex);job = req.getParameter(job);Java实用教程ta = req.getParameter(ta); /进行输出res.setContentType(text/html; chars

539、et=GB2312);PrintWriter out = res.getWriter();out.println();out.println(注册信息返回结果);out.println( 姓名: + parseChinese(name);out.println( 身份证号: + number);out.println( 性别: + parseChinese(sex) + 职业: + parseChinese(job);out.println(个性化宣言: + parseChinese(ta) + ); Java实用教程图13.3 用户输入注册信息Java实用教程图13.4 Servlet返回信

540、息Java实用教程13.3.2 编译、配置编译、配置Servlet 安装的Java包是没有带Servlet的JAR文件,所以将D:Apache Tomcat 4.0commonlib目录下的Servlet.jar配置到路径包的安装路径下库的扩展目录中,编译时会自动连接库,如本书配置到的目录为D:j2sdk1.4.0_01jrelibext。在命令行提示符下键入命令javac UserServlet.java编译文件,生成类UserServlet.class。Java实用教程 Servlet是服务器端组件,所以必须配置到服务器端。对于Tomcat 4.0服务器,将index.html配置到物理路

541、径D:Apache Tomcat 4.0webappsROOTuser目录下,对应的网络路径就是http:/192.100.100.43:8080/user/index.html;将UserServlet配置到物理路径下的D:Apache Tomcat 4.0webappsexamplesWEB-INFclassesuser目录下,对应的网络地址就是http:/192.100.100.43:8080/examples/Servlet/user.UserServlet。这些配置信息由index.html中的Action属性标明。Java实用教程 如果希望能够配置到根目录下,则在开始-程序-Apa

542、che Tomcat 4.0-Configuration中单击EditServer Configuration,然后找到行: !- - -删除第二个,将以上语句变成: Java实用教程 将机器重启动,使得配置文件生效,并在D:Apache Tomcat 4.0webappsROOTWEB-INF路径下建立classes目录,然后将UserServlet.java源文件中的语句行package user;去掉,重新编译成.class类文件并放入此目录,则action属性对应的网络地址为http:/192.100.100.43:8080/Servlet/ UserServletJava实用教程13

543、.4 Applet与与Servlet通信通信 Applet与Servlet的通信过程的基本原理相当于HTML网页的POST请求。首先两者之间建立一个连接,使用URLConnection类对象打开连接后,Applet将请求发送给Servlet,Servlet处理请求并返回处理结果。注意,发送请求数据时一定用URLEncoder类的Encode方法进行格式编码,在Servlet端还需用URLDecoder类的Decode方法进行格式解码。 在HTTP协议中POST请求是以参数名=参数值的方式自动进行URL编码后传送的,编程中要手工实现,例如名-值对Java实用教程 qry = SELECT num

544、ber,code,score from chengji WHERE code=3001进行URL编码如下: String qry = URLEncoder.encode(qry,UTF-8) + = + URLEncoder.encode(qryString,UTF-8); 建立连接时,注意将DbServlet配置到路径D:Apache Tomcat 4.0webappsROOTWEB-INFclasses下。Java实用教程String str = http:/192.100.100.43:8080/Servlet/DbServlet;URL urlName = new URL(str);打

545、开连接。URLConnection uc = urlName.openConnection();设置参数。uc.setDoOutput(true);uc.setDoInput(true);uc.setUseCaches(false);Java实用教程 uc.setRequestProperty(Content-type,application/x-www-form-urlencoded); 得到数据流发送格式转换后的POST请求。 DataOutputStream dos = new DataOutputStream(uc.getOutputStream(); dos.writeBytes(q

546、ry); 在DbServlet中接收数据并进行解码。 String qry = req.getParameter(qry); qry = URLDecoder.decode(qry,UTF-8);Java实用教程 【例13.2】编写Applet和Servlet交互的程序,使得用户在Applet界面(见图13.5)上输入数据库查询语句,单击“查询”按钮后,后台Servlet接收请求,对后台数据库进行查询,并将查询结果返回到Applet界面的文本区域内。图13.5 Applet用户界面Java实用教程图13.6 Applet和Servlet交互原理图Java实用教程13.4.1 Servlet文件

547、文件 首先书写查询数据库的Servlet文件,编译通过后配置到上面提到的路径。/程序文件名DbServlet.javaimport javax.Servlet.*;import javax.Servlet.http.*;import java.util.*;import java.sql.*;import java.io.*;import .*;Java实用教程public class DbServlet extends HttpServletpublic void doPost(HttpServletRequest req, HttpServletResponse res) throws I

548、OException, ServletExceptionPrintWriter out = res.getWriter();res.setContentType(text/html;charset=GB2312); /得到Applet请求参数,解码后输出String qry = req.getParameter(qry);qry = URLDecoder.decode(qry,UTF-8);out.println(qry);Connection dbCon = null;tryJava实用教程 /同数据库建立连接Class.forName(sun.jdbc.odbc.JdbcOdbcDrive

549、r);String dbURL = jdbc:odbc:STU;dbCon = DriverManager.getConnection(dbURL,);PreparedStatement p = dbCon.prepareStatement(qry);ResultSet rs = p.executeQuery();/输出查询结果while(rs.next()out.print(rs.getString(1);out.print(rs.getString(2) + );out.println(rs.getInt(3);Java实用教程catch(Exception e)out.println(读

550、写数据库出错: + e.getMessage();finallytrydbCon.close();out.close();catch(Exception e)Java实用教程 out.println(关闭数据库连接出错: + e.getMessage(); ;Java实用教程13.4.2 Applet文件文件编写与Servlet通信的Applet文件。/程序文件名DbApplet.javaimport java.awt.*;import java.applet.*;import java.awt.event.*;import java.io.*;import .*;public class D

551、bApplet extends Applet implements ActionListenerTextField tfQuery;Java实用教程TextArea taResults;Button btnExecute;URL chatURL; public void init()Panel pa = new Panel();pa.setLayout(new FlowLayout(FlowLayout.LEFT);pa.add(new Label(查询串:);tfQuery = new TextField(SELECT number,code,score from chengji WHERE

552、 code=3001,50);Java实用教程pa.add(tfQuery);btnExecute = new Button(查询);btnExecute.addActionListener(this);pa.add(btnExecute);add(North,pa);taResults = new TextArea(30,60);add(Center,taResults);chatURL = getCodeBase(); public void actionPerformed(ActionEvent evt)Java实用教程String lbl = evt.getActionCommand(

553、);if(lbl.equals(查询) String qryString = tfQuery.getText(); try /查询串编码 String qry = URLEncoder.encode(qry,UTF-8) + = + URLEncoder.encode(qryString,UTF-8); /打开到DbServlet的连接String str = http:/192.100.100.43:8080/Servlet/DbServlet;Java实用教程URL urlName = new URL(str);URLConnection uc = urlName.openConnecti

554、on();uc.setDoOutput(true);uc.setDoInput(true);uc.setUseCaches(false); uc.setRequestProperty(Content-type,application/x-www-form-urlencoded);/获得输出流 DataOutputStream dos = new DataOutputStream(uc.getOutputStream();Java实用教程 /发送编码的查询串 dos.writeBytes(qry); dos.close();/获取结果,输出InputStreamReader in = new I

555、nputStreamReader(uc.getInputStream();int chr = in.read();while(chr != -1)taResults.append(String.valueOf(char)chr);chr = in.read();Java实用教程in.close();catch(MalformedURLException e)taResults.setText(e.toString();catch(IOException e)taResults.setText(e.toString(); Java实用教程13.4.3 HTML文件文件 最后编写HTML文件,用户

556、最好将它转换成使用插件的文件,使用插件的文件具有较好的应用性。 Java实用教程13.4.4 结果显示结果显示 本例中用到的表为STU配置下的Chengji表,部分记录如图13.7所示。查询串分别为: SELECT number,code,score from chengji WHERE code= 2001 SELECT number,code,score from chengji WHERE code= 1002 而查询结果如图13.8所示。对照Chengji表,得出查询结果完全正确。Java实用教程图13.7 STU库中的Chengji表Java实用教程图13.8 查询结果的输出Java

557、实用教程习习 题题 1. 编写Servlet程序,进行数据库访问,将数据库结果以表格的形式显示在HTML网页上。 2. 编写Applet和Servlet的交互程序,Applet请求打开一个文本文件,Servlet接收文件的路径和名称,返回文本文件的内容。在Applet界面上的文本框内输入文件路径以及名称,单击“请求”按钮,得到Servlet的响应,返回的内容输出到Applet界面上的文本区域内。设计具体界面时可参考图13.9。Java实用教程图13.9 用户界面Java实用教程第14章 Java读写XML技术 14.1 XML简介简介 14.2 SAX接口解析接口解析XML 14.3 DOM接

558、口解析接口解析XML 习习 题题 Java实用教程14.1 XML 简简 介介14.1.1 XML定义定义 XML是SGML一个简化而严格的子集,特别是为Web应用设计的,具有可扩展性、结构性和可检验性。 可扩展性指用户可以根据需要自定义新的标识以及属性名,更好地从语义上修饰数据。 结构性指XML文件结构可以嵌套,也可以复杂到任意程度。 可校验性指XML文件文件可以包括一个语法描述,应用程序可以通过语法描述对此文件进行结构检验。Java实用教程14.1.2 XML分类分类图14.1 XML相关标准的体系结构Java实用教程1. 元语言标准元语言标准用来描述标准的元语言,即XML标准。 XML相

559、关标准主要分为三类,分别是元语言标准、基础标准和应用标准。Java实用教程 2. 基础标准基础标准 为XML进一步实用化制定的标准,共分为五类:外围标准、核心标准、操作标准、样式与链接标准、内容描述标准。 (1) 外围标准指Internet网络上统一应用的标准: HTTP协议采用请求/应答方式,客户端向服务器提交请求方式、URI、协议版本、客户端信息等,服务器向客户端返回状态信息、实体信息以及实体内容等。 URI/URL指资源定位符,用来在网络上实现快速资源定位。 Unicode指Internet网上统一传输数据的标准编码。Java实用教程 (2) 核心标准是XML核心的标准。 (3) 操作标

560、准为XML文档的处理提供有效的方法与规则,DOM是与平台无关的,提供一个编程接口。Schema是对DOM的补充,提供一种更为严格的描述XML文档的结构、属性、数据类型等的方法。Java实用教程 (4) 样式与链接标准。 CSS是XML文档显示的样式标准。 XSL标准可将XML文档形成树状结构,采用元素节点匹配的方式进行转换,因而该标准提供转换和显示的标准。 XSLT标准是从XSL中分离出来的,是XML文档的转换标准,可以将XML文档转换为HTML文档并进行显示处理。 (5) 内容描述标准。 RDF(Resourse Description Format)采用XML语法格式处理元数据的应用,是为

561、描述图像文档和它们之间的相互关系定义的一个简单数据模型,为进行资源描述定义了资源描述的规则。Java实用教程 3. 应用标准应用标准 XML标准是Internet时代的ASCII标准,主要针对具体的领域进行应用,如cXML是指电子商务XML应用标准、voiceXML指语音XML等。Java实用教程14.1.3 XML文档的书写文档的书写图14.2 XML文档举例Java实用教程14.1.4 XML文档的解析文档的解析图14.3 XML文档的处理过程Java实用教程14.2 SAX接口解析接口解析XML14.2.1 解析的步骤解析的步骤(1) 创建SAX解析工厂的实例。SAXParserFact

562、ory spf = SAXParserFactory.newInstance();(2) 创建一个SAX解析器。SAXParser sp = spf.newSAXParser();(3) 得到SAX的处理器(处理器由用户自己编写实现)。SAXHandler handler = new SAXHandler(); (4) 使用用户创建的处理器,解析器解析文件。sp.parse(new InputSource(reader), handler);Java实用教程14.2.2 相关类相关类 在J2sdk1.4中的SAX版本为2.0,它提供DefaultHandler(org.xml.sax.help

563、ers.DefaultHandler)接口,通过这个接口实现自己的解析器。接口中需要实现的解析函数为: public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException 读取XML数据的节点元素开始时触发,需要实现这个方法进行标记元素的名字的操作。Java实用教程 public void endElement(String uri, String localName, String qName) throws SAXException 处

564、理节点元素终止时触发,可以添加代码来将节点数据进行存储。 public void characters(char ch, int start, intlength) throws SAXException 处理节点之间的数据,可以添加代码来读取节点间的数据值。Java实用教程 【例14.1】编写一个SAX处理器,对14.1节中的person.xml进行解析,输出XML文件节点的标签和节点的值。 分析:类SAXHandler是一个处理类,实现这个DefaultHandler接口时覆盖了上述三个方法,将读取的节点标签和节点的值存入到Hashtable对象中。类中提供了一个方法,返回读取的名-值对的

565、Hashtable对象。输出结果如图14.4所示。源程序代码如下:/程序文件名为Parse.javaimport java.io.*; import java.util.Hashtable;import org.w3c.dom.*; Java实用教程import org.xml.sax.*;import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;import org.xml.sax.helpers.*;public class Parsepublic static void main(Strin

566、g args)tryJava实用教程File file = new File(person.xml);FileReader reader = new FileReader(file);/创建解析工厂实例 SAXParserFactory spf = SAXParserFactory.newInstance(); /创建解析器 SAXParser sp = spf.newSAXParser(); /创建处理类实例 SAXHandler handler = new SAXHandler(); /解析 sp.parse(new InputSource(reader), handler); Hasht

567、able hashTable = handler.getTable(); /输出数据Java实用教程System.out.println(教师信息表); System.out.println(姓名:+ (String)hashTable.get(new String(name); System.out.println(学院: + (String)hashTable.get(new String(college); System.out.println(电话: + (String)hashTable.get(new String(telephone); System.out.println(职称

568、: + (String)hashTable.get(new String(title); catch(Exception e) System.out.println(e.getMessage(); ;Java实用教程/自定义处理类class SAXHandler extends DefaultHandler private Hashtable table = new Hashtable(); private String currentElement = null; private String currentValue = null; public Hashtable getTable()

569、return table; /覆盖startElement方法,取出节点标签 public void startElement(String uri,String localName,String qName,Attributes attributes) Java实用教程currentElement = qName; /覆盖characters方法,取出节点值 public void characters(char ch, int start, int length) throws SAXException currentValue = new String(ch, start, length

570、); /覆盖endElement方法,放入HashtableJava实用教程 public void endElement(String uri,String localName,String qName) throws SAXException if (currentElement.equals(qName) table.put(currentElement, currentValue); ;Java实用教程图14.4 解析person.xml文件后输出结果Java实用教程14.3 DOM接口解析接口解析XML14.3.1 解析的步骤解析的步骤1. 从从DOM接口写接口写XML的步骤的步骤(

571、1) 创建DocumentBuilderFactory的一个实例;(2) 创建DocumentBuilder的一个新实例;(3) 构建一个DOM对象;(4) 创建ROOTELEMENT对象;(5) 创建单个ELEMENT节点;(6) ELEMENT创建节点的值;(7) 将ELEMENT挂接到ROOT上;(8) 写入XML文件。Java实用教程2. 从从DOM接口读接口读XML的文件步骤的文件步骤(1) 创建DocumentBuilderFactory的一个实例;(2) 创建DocumentBuilder的一个新实例;(3) 根据已有的XML文件构建一个DOM对象;(4) 得到ROOTELEME

572、NT对象;(5) 得到单个ELEMENT节点;(6) 得到ELEMENT创建节点的值。Java实用教程14.3.2 相关类相关类1. DocumentBuilderFactory类类public abstract class DocumentBuilderFactory extends Object定义工厂API,使得应用程序得到解析器从XML文档中产生的DOM对象树。public static DocumentBuilderFactory newInstance() throws FactoryConfigurationError得到DocumentBuilderFactory的一个实例,这

573、个实例某个时刻只能用于一个线程。public abstract DocumentBuilder newDocumentBuilder() throws ParserConfigurationException使用当前配置的方法创建一个新的DocumentBuilder的实例。Java实用教程2. DocumentBuilder类类public abstract class DocumentBuilder extends Object定义从XML文档得到DOM文档的API。public abstract Document newDocument()得到DOM文档对象的一个新实例,用来构建DOM树

574、。public Document parse(File f) throws SAXException, IOException解析给定的XML文档f,返回DOM文档对象。Java实用教程3. Document类类public interface Document extends NodeDocument接口代表整个XML文档。public Element createElement(String tagName) throws DOMException创建指定的类型的元素tagName。public Text createTextNode(String data)使用给定的data字符串创建节

575、点元素的值。Java实用教程 4. Element类类 public interface Element extends Node Element接口代表XML文档中的一个元素。 public NodeList getElementsByTagName(String name) 返回给定的name元素下面的所有节点列表,以前向遍历的方式给出。Java实用教程5. NodeList类类NodeList接口给出一个节点集合,有以下两个方法:public int getLength()返回节点的个数。public Node item(int index)返回第index个节点。Java实用教程 6.

576、 Node类类 Node接口是整个文档对象模型中最主要的数据类型,它表示文档树中单一的节点。 Node getFirstChild() 返回节点的第一个孩子节点。 String getNodeValue() 返回叶子节点的值。Java实用教程14.3.3 实例实例 【例14.2】在用户界面(见图14.5)上输入个人信息后,单击“确定”按钮,程序收集用户信息,存成文档user.xml并显示如下。单击“显示”按钮,读取user.xml文件,将节点标签和对应的节点值显示在文本区域内。王飞111122197904290902男军队海纳百川,有容乃大;壁立千仞,无欲则刚Java实用教程1. 程序源文件程

577、序源文件/程序文件名UsePanel.javaimport java.awt.*;import java.awt.event.*;import java.applet.*;import java.applet.Applet;import java.io.*;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.*;Java实用教程public class UsePanel extends Applet implements Actio

578、nListenerLabel lblName,lblNumber,lblSex,lblJob,lblText;TextField tfName,tfNumber;Checkbox chMale, chFemale;CheckboxGroup c;TextArea taText;Choice chJob;Button btnOk,btnDisplay;Panel p1,p2,p3,p4,p5,p6,p7,p8,p9;String strName,strNumber,strSex,strJob,strText;public void init()Java实用教程/初始化界面对象lblName =

579、new Label(姓名:);lblNumber = new Label(身份证号:);lblSex = new Label(性别);lblJob = new Label(职业);lblText = new Label(个性化宣言:);tfName = new TextField(23);tfNumber = new TextField(20);taText = new TextArea(10,20);c = new CheckboxGroup();chMale = new Checkbox(男,c,true);chFemale = new Checkbox(女,c,false);chJob

580、= new Choice();Java实用教程chJob.add(计算机业);chJob.add(医生);chJob.add(教师);chJob.add(军队);btnOk = new Button(确定);btnDisplay = new Button(显示);p1 = new Panel();p2 = new Panel();p3 = new Panel();p4 = new Panel();p5 = new Panel();p6 = new Panel();Java实用教程p7 = new Panel(new BorderLayout();p8 = new Panel();p9 = ne

581、w Panel(new BorderLayout(); /设置界面 p1.add(lblName);p1.add(tfName);p2.add(lblNumber);p2.add(tfNumber);p3.add(lblSex);p3.add(chMale);p3.add(chFemale);Java实用教程p4.add(lblJob);p4.add(chJob);p5.add(p3);p5.add(p4);p6.setLayout(new BorderLayout();p6.add(p1,BorderLayout.NORTH);p6.add(p2,BorderLayout.CENTER);p

582、6.add(p5,BorderLayout.SOUTH);p7.add(lblText,BorderLayout.NORTH);p7.add(taText,BorderLayout.CENTER);Java实用教程p8.setLayout(new FlowLayout(FlowLayout.CENTER,30,10);p8.add(btnOk);p8.add(btnDisplay);p9.add(p6,BorderLayout.NORTH);p9.add(p7,BorderLayout.CENTER);p9.add(p8,BorderLayout.SOUTH);add(p9);/添加监听事件b

583、tnOk.addActionListener(this);btnDisplay.addActionListener(this);Java实用教程btnDisplay.setEnabled(false);strName = new String();strNumber = new String();strSex = new String();strJob = new String();strText = new String();public void actionPerformed(ActionEvent evt)String arg = evt.getActionCommand(); /收集

584、用户信息并写入XML文件if(arg.equals(确定)Java实用教程strName = tfName.getText().trim();strNumber = tfNumber.getText().trim();if(chMale.getState()strSex = 男;elsestrSex = 女;strJob = chJob.getSelectedItem();strText = taText.getText().trim();try /创建新的文档对象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(

585、);Java实用教程DocumentBuilder db = dbf.newDocumentBuilder();Document doc = db.newDocument();/创建元素Element root = doc.createElement(UserData);Element eName = doc.createElement(Name);Element eNumber = doc.createElement(Number);Element eSex = doc.createElement(Sex);Element eJob = doc.createElement(Job);Elem

586、ent eText = doc.createElement(Text);/添加节点Java实用教程root.appendChild(eName);root.appendChild(eNumber);root.appendChild(eSex);root.appendChild(eJob);root.appendChild(eText);/添加值eName.appendChild(doc.createTextNode(n + strName + n);eNumber.appendChild(doc.createTextNode(n + strNumber + n);eSex.appendChil

587、d(doc.createTextNode(n + strSex + n);eJob.appendChild(doc.createTextNode(n + strJob + n);eText.appendChild(doc.createTextNode(n + strText + n);Java实用教程/创建文件对象File f = new File(user.xml);FileOutputStream fOut = new FileOutputStream(f);/初始化xml文件fOut.write(n.getBytes();/写入文件fOut.write(root.toString().g

588、etBytes();fOut.flush();fOut.close();btnDisplay.setEnabled(true);catch(Exception e)Java实用教程System.out.println(e.getMessage(); /读取XML文件并输出到文本区域else if(arg.equals(显示) try /得到XML文档对象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Documen

589、t doc = db.parse(user.xml); Element root = doc.getDocumentElement(); /获取叶子节点值Java实用教程strName = root.getElementsByTagName(Name).item(0).getFirstChild().getNodeValue().trim();strNumber =root.getElementsByTagName(Number).item(0).getFirstChild(). getNodeValue().trim();strSex = root.getElementsByTagName(

590、Sex).item(0).getFirstChild(). getNodeValue().trim();strJob = root.getElementsByTagName(Job).item(0).getFirstChild(). getNodeValue().trim();strText = root.getElementsByTagName(Text).item(0).getFirstChild(). getNodeValue().trim();/输出到文本区域Java实用教程 taText.setText(); taText.append(姓名: + strName + n身份证号:

591、+strNumber + n性别: + strSex + n职业: + strJob + n个性化宣言:n + strText);catch(Exception e) System.out.println(e.getMessage(); public static void main(String args)Java实用教程Frame f = new Frame(收集用户界面); /关闭窗口退出程序f.addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent evt)System.exit(0););/

592、定义类实例UsePanel p = new UsePanel();p.init();f.add(Center,p);f.setSize(600,450);f.show();Java实用教程 2. 结果分析结果分析 图14.5显示用户输入的信息,初始化时“显示”按钮变灰,无法使用。单击“确定”按钮时,用户输入的信息存入user.xml文件,“显示”按钮可以使用,此时单击“显示”按钮,将得到如图14.6所示的输出结果。文本区域内是从user.xml文件中读取的节点标签和相应的节点值。Java实用教程图14.5 信息输入Java实用教程图14.6 单击“显示”按钮后读出XML文件内容Java实用教程

593、习习 题题1. 编写test.xml文件,要求在浏览器中的显示如下:王月交通大学2673457教授Java实用教程 2. 通过SAX接口将本章person.xml文件用表的格式显示在图形用户界面上,要求文件中的节点标签分别为表的列名称,相应节点的值为一条记录。 3. 根据习题1设计图形用户界面,输入各项内容后,用DOM接口存入my.xml文件。 4. 用DOM接口访问例14.1的person.xml文件,并用树形结构显示在图形用户界面上,要求文件中的节点名称为树结点名称,文件中的值为树的叶子结点。 5. 编写Servlet,读取例14.2的user.xml文件,将内容输出到HTML页面上,显示结果如第13章的图13.4所示。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号