Login
升级VIP 登录 注册 安全退出
当前位置: 首页 > PPT模板 > 教师培训 > Java教程java培训ppt课件(2010新版)

Java教程java培训ppt课件(2010新版)

收藏

Java教程java培训ppt课件(2010新版)

Java教程java培训ppt课件(2010新版)

Java教程java培训ppt课件(2010新版)

Java实用教程新版Java培训教程JavaJavaJava实用教程目录第1章Java环境及配置第2章Java基本语法第3章类和接口第4章JavaApplet第5章Java图形处理第6章Java用户界面技术第7章异常、事件和多线程机制第8章输入输出技术第9章Java数据库技术第10章Java安全技术第11章Java网络技术(一)第12章Java网络技术(二)第13章Servlet技术第14章Java读写XML技术Java实用教程第1章Java环境及配置1.1Java概述1.2Java语言的特点1.3Java应用分类1.4JDK包的下载与安装1.5Java环境配置1.6例子程序习题Java实用教程1.1Java概述Java是一种编程语言,它提供了一个同时用于程序开发、应用和部署的环境。Java语言主要定位于网络编程,使得程序可以最大限度地利用网络资源。Java实用教程1.2Java语言的特点1.跨平台性所谓的跨平台性,是指软件可以不受计算机硬件和操作系统的约束而在任意计算机环境下正常运行。这是软件发展的趋势和编程人员追求的目标。之所以这样说,是因为计算机硬件的种类繁多,操作系统也各不相同,不同的用户和公司有自己不同的计算机环境偏好,而软件为了能在这些不同的环境里正常运行,就需要独立于这些平台。Java实用教程而在Java语言中,Java自带的虚拟机很好地实现了跨平台性。Java源程序代码经过编译后生成二进制的字节码是与平台无关的,但是可被Java虚拟机识别的一种机器码指令。Java虚拟机提供了一个字节码到底层硬件平台及操作系统的屏障,使得Java语言具备跨平台性。Java实用教程2.面向对象面向对象是指以对象为基本粒度,其下包含属性和方法。对象的说明用属性表达,而通过使用方法来操作这个对象。面向对象技术使得应用程序的开发变得简单易用,节省代码。Java是一种面向对象的语言,也继承了面向对象的诸多好处,如代码扩展、代码复用等。Java实用教程3.安全性安全性可以分为四个层面,即语言级安全性、编译时安全性、运行时安全性、可执行代码安全性。语言级安全性指Java的数据结构是完整的对象,这些封装过的数据类型具有安全性。编译时要进行Java语言和语义的检查,保证每个变量对应一个相应的值,编译后生成Java类。运行时Java类需要类加载器载入,并经由字节码校验器校验之后才可以运行。Java类在网络上使用时,对它的权限进行了设置,保证了被访问用户的安全性。Java实用教程4.多线程多线程在操作系统中已得到了最成功的应用。多线程是指允许一个应用程序同时存在两个或两个以上的线程,用于支持事务并发和多任务处理。Java除了内置的多线程技术之外,还定义了一些类、方法等来建立和管理用户定义的多线程。Java实用教程5.简单易用Java源代码的书写不拘泥于特定的环境,可以用记事本、文本编辑器等编辑软件来实现,然后将源文件进行编译,编译通过后可直接运行,通过调试则可得到想要的结果。Java实用教程1.3Java应用分类1.应用程序典型的通用程序可以在具备Java运行环境的设备中独立运行,它又分为:GUI应用程序:即图形用户界面程序,可实现丰富的输入界面和输出显示。命令行程序:无需界面,只需在命令行下运行,运行结果只在后台发生变化,可以将输出存放到文件中。嵌入式应用程序:Java语言的平台独立性决定了它可以嵌入到不同的设备中,且只需具备必要的运行环境即可。Java实用教程2.Servlets服务器端应用程序服务器端的应用程序用来收集客户端的数据输入,对数据进行处理之后,返回相应的响应给客户。它主要用来实现与客户端的交互。Java实用教程3.Applets小应用程序Applets应用于网络上,嵌入在HTML网页中,支持Java的浏览器都可以对它进行解释并运行。通常通过一个HTML标签来识别并运行Applets。小应用程序的类在服务器端,当浏览器显示网页时,它随之下载到本地,由本地的浏览器载入运行。Java实用教程1.4JDK包的下载与安装JavaDevelopKit简称为JDK,是Sun公司免费发行的软件包,可以从Sun网站http://www.sun.com免费下载,也可以从其它国内地址下载。JDK版本从1.02开始,目前版本发展到1.4,其中高级版本对低级版本实现向下兼容。运用这个软件包,就可以对Java源程序进行编译和运行。本书中下载使用的JDK包为j2sdk-1_4_0_012-windows-i586.exe。下载后双击图标,即可进行安装,默认的安装目录为C:\j2sdk1.4.0_01。本书作者将安装目录改为D:\j2sdk1.4.0_01。Java实用教程1.5Java环境配置JDK包安装完成后,需要设置环境变量。用鼠标右键单击桌面上的图标“我的电脑”,选择“属性”项,出现标题为“系统特性”的对话框,点击“高级”标签,可以看见有一个“环境变量”按钮,如图1.1所示。Java实用教程图1.1“系统特性”对话框Java实用教程单击“环境变量”按钮,可以看见本机环境变量,如图1.2所示。上面为用户变量,下面为系统变量,随着操作系统或用户环境的不同,变量名、值有所不同。这里需要修改三个用户变量:include、lib和path,分别将JDK包安装之后的相应路径包含到这三个用户变量中。Java实用教程图1.2“环境变量”对话框Java实用教程选中include变量,单击“编辑”按钮,弹出标题为“编辑用户变量”的对话框,如图1.3所示。在变量值一栏的最后添加“;D:\j2sdk1.4.0_01\include”,“;”表示与前面的各项隔开,后面的路径是JDK包的安装路径下的include目录。图1.3为作者修改include变量的情况,注意你的安装路径可能与作者的有所不同,要以你的安装路径为基准进行修改。Java实用教程图1.3编辑include变量Java实用教程选中lib变量,单击“编辑”按钮,弹出标题为“编辑用户变量”的对话框,如图1.4所示。在变量值一栏的最后添加“;D:\j2sdk1.4.0_01\lib”,“;”表示与前面的各项隔开,后面的路径是JDK包的安装路径下的lib目录。图1.4为作者修改lib变量的情况,注意你的安装路径可能与作者的有所不同,要以你的安装路径为基准进行修改。Java实用教程图1.4编辑lib变量Java实用教程选中path变量,单击“编辑”按钮,弹出标题为“编辑用户变量”的对话框,如图1.5所示。在变量值一栏的最后添加“;D:\j2sdk1.4.0_01\bin”,“;”表示与前面的各项隔开,后面的路径是JDK包的安装路径下的bin目录。图1.5为作者修改path变量的情况,注意你的安装路径可能与作者的有所不同,同样要以你的安装路径为基准进行修改。Java实用教程图1.5编辑path变量Java实用教程1.6例子程序【例1.1】源程序名称为HelloWorld.java,命令行提示符下输出字符串“HelloWorld”。源代码如下://程序文件名称为HelloWorld.javapublicclassHelloWorld{publicstaticvoidmain(Stringargs[]){System.out.println("HelloWorld");}}Java实用教程用记事本或者专用的编辑工具如EditPlus等进行编辑,并将文件存为HelloWorld.java。建议使用像EditPlus这样的编辑软件,可使得代码更加清晰且风格良好。运行“开始”菜单→程序→附件→命令提示符,载入命令行程序,在命令行状态下,进入源程序所在的目录,图1.6所示的例子程序的目录在“E:\_Work\Java\sample”下,然后键入命令“javacHelloWorld.java”。若编译不通过,会产生错误提示。若编译通过,则没有任何提示,同时进入命令行等待状态,如图1.6所示。这时,命令行虽然没有提示,但在源程序的路径下生成一个新的文件为HelloWorld.class。这个.class文件就是编译后生成的类文件,运行此文件,需在命令行状态中键入命令“javaHelloWorld”,然后按回车键,此时程序就会运行并输出“HelloWorld”。输出完毕,立即退出程序,进入命令行等待状态,如图1.7所示。Java实用教程图1.6编译源程序HelloWorldJava实用教程图1.7运行HelloWorld应用程序Java实用教程这里用到的命令Javac和Java都是JDK软件包自带的。从JDK安装路径的bin目录下可以看到javac.exe,这是编译程序,源程序编译通过后就生成.class文件;而Java.exe就是载入类的运行程序,运行时根据源程序的指令要求产生正确的输出或结果。如果没有进行环境配置,直接编译或者运行Java源程序,系统会提示找不到这些命令,所以必须进行环境配置后再使用。Java实用教程【例1.2】小应用程序的例子。输出“HelloWorld!”,如图1.8所示。源程序代码如下://程序文件名称为HelloApplet.javaimportjava.awt.Graphics;importjava.applet.Applet;publicclassHelloAppletextendsApplet{publicvoidpaint(Graphicsg){g.drawString("HelloWorld!",50,25);}}Java实用教程小应用程序代码书写和编译完成后,无法独立运行,需要一个载体或者容器。下面的HTML网页代码就是小应用程序载入的容器。HTMLTestPage Java实用教程HelloAppletwillappearbelowinaJavaenabledbrowser.
Java实用教程图1.8Applet显示“HelloWorld!”Java实用教程习题1.简述Java的特点。2.简述Java的分类情况。3.进行Java环境的安装和配置。4.编写应用程序,屏幕上输出“欢迎来到Java世界!”。5.编写Applet,输出“欢迎来到Java世界!”。Java实用教程第2章Java基本语法2.1Java程序的构成2.2数据类型、变量和常量2.3运算符和表达式2.4流程控制2.5数组的使用习题Java实用教程2.1Java程序的构成2.1.1逻辑构成Java源程序逻辑构成分为两大部分:程序头包的引用和类的定义。1.程序头包的引用主要是指引用JDK软件包自带的包,也可以是自己定义的类。引用之后程序体中就可以自由应用包中的类的方法和属性等。Java实用教程2.类的定义Java源程序中可以有多个类的定义,但必须有一个主类,这个主类是Java程序运行的入口点。在应用程序中,主类为包含main方法的类;在Applet中,主类为用户自定义的系统Applet类的扩展类。在Java源程序中,主类的名字同文件名一致。类的定义又包括类头声明和类体定义。类体中包括属性声明和方法描述。下面来看一个例子,其中斜体表示的语句行为主类类头,主类类头下面从大括号“{”开始到“}”结束的部分称为主类类体。Java实用教程【例2.1】下面是一个应用程序,也是一个Applet,既可以在命令行下运行,也可以嵌入到HTML网页中用appletviewer命令运行。运行时在界面上的第一个文本框中输入你的名字,按回车键后,在第二个文本框中会显示“XXX,欢迎你来到Java世界!”,运行结果如图2.1所示。//程序文件名称为WelcomeApplet.java注释语句vent.;java.awt.eimport;java.awt.importt.;java.appleimport引入包publicclassWelcomeAppletextendsAppletimplementsActionListener主类类头{Java实用教程txtDisp;TextFieldtxtName;TextFieldlblName;Label属性}r(this);ionListeneame.addActtxtNp);add(txtDise);add(txtName);add(lblNam20);TextField(newisptxtD8);TextField(newametxtN);""newLabel(lblName{init()voidpublic请输入您的名字init方法Java实用教程);"Java"getText()t(txtName.isp.setTextxtD{e)onEventormed(ActiactionPerfvoidpublic世界欢迎你来到actionPerformed方法Java实用教程}a.start();f.show();400,300);f.setSize(a);,Center"f.add("a.init();let();WelcomeAppnewaletWelcomeApp;}}t(0);System.exi{evt)wEventsing(WindowindowClovoidpublicter()){WindowAdapnewwListener(f.addWindo);""newFrame(fameFr{args[])gmain(Strinvoidstaticpublic欢迎main主方法Java实用教程图2.1程序界面Java实用教程2.1.2物理构成Java源程序物理上由三部分构成,分别为语句、块和空白。(1)语句指一行以分号“;”结束的语句。(2)块指用括号对{}界定的语句序列,块可以嵌套使用。(3)空白指语句之间、块内部或者块之间的空白行。空白不影响Java源程序的编译和运行,适当地运用空白,可以形成良好的代码风格。Java实用教程在例1.1中,LabellblName;TextFieldtxtName;TextFieldtxtDisp;都是语句,而{lblName=newLabel("请输入您的名字:");txtName=newTextField(8);txtDisp=newTextField(20);add(lblName);add(txtName);add(txtDisp);txtName.addActionListener(this);}是块,语句之间、块之间或块内部的空行都为空白。Java实用教程2.1.3注释语句注释语句主要用来进行一些说明,或者标记一些无用的程序语句。有两种注释方法,行注释为以//开始的行;块注释以/开始和结束,Java编译器忽略注释后的程序语句或说明。例如,下面的语句就是注释语句用来说明程序文件名称的。//程序文件名称为WelcomeApplet.java上述的语句注释可以更改为:/程序文件名称为WelcomeApplet.java/或/程序文件名称为WelcomeApplet.javaJava实用教程2.1.4标识符、关键字和转义符在Java语言中,标识符是赋予变量、类和方法等的名称。标识符由编程者自己指定,但需要遵循一定的语法规范:(1)标识符由字母、数字、下划线(_)、美元符号($)组成,但美元符号用得较少。(2)标识符从一个字母、下划线或美元符号开始。(3)Java语言中,标识符大小写敏感,必须区别对待。(4)标识符没有最大长度的限制,但最好表达特定的意思。(5)标识符定义不能是关键字。Java实用教程关键字又称保留字,是指Java语言中自带的用于标志数据类型名或者程序构造名等的标识符,如public、double等。转义符是指一些有特殊含义的、很难用一般方式表达的字符,如回车、换行等。所有的转义符以反斜线(\)开头,后面跟着一个字符来表示某个特定的转义符,如表2.1所示。Java实用教程表2.1转义符引用方法含义\b退格\t水平制表符Tab\n换行\f表格符\r回车\'单引号\"双引号\\反斜线Java实用教程2.2数据类型、变量和常量2.2.1数据类型Java编程语言定义了八种基本的数据类型(见表2.2),共分为四类:整数类(byte、short、int、long)、文本类(char)、浮点类(double、float)和逻辑类(boolean)。Java实用教程表2.2Java的数据类型分类数据类型关键字占字节数缺省数值取值范围字节型byte80-27~27-1短整型short160-215~215-1整型int320-231~231-1整数类长整型long640-263~263-1文本类字符型char16′\u0000′′\u0000′~′\uFFFF′浮点型float320.0F—浮点类双精度型double640.0D—逻辑类逻辑型boolean8FalseTrue、FalseJava实用教程1.整数类(1)采用三种进制——十进制、八进制和十六进制。2——十进制值是2;077——首位的0表示这是一个八进制的数值;0xBAAC——首位的0x表示这是一个十六进制的数值。(2)具有缺省int。(3)用字母“L”和“l”定义long。(4)所有Java编程语言中的整数类型都是带符号的数字。Java实用教程2.文本类(1)代表一个16bitUnicode字符。(2)必须包含用单引号('')引用的文字。(3)使用下列符号:'a'——一个字符。'\t'--一个制表符。'\u????'--一个特殊的Unicode字符,????应严格使用四个十六进制数进行替换。Java实用教程3.浮点类默认为double类型,如果一个数字包括小数点或指数部分,或者在数字后带有字母F或f(float)、D或d(double),则该数字为浮点数。Java实用教程4.逻辑类boolean数据类型有两种值:true和false。例如:booleanflag=true;上述语句声明变量flag为boolean类型,它被赋予的值为true。Java实用教程2.2.2变量与常量常量是指整个运行过程中不再发生变化的量,例如数学中的π=3.1415……,在程序中需要设置成常量。而变量是指程序的运行过程中发生变化的量,通常用来存储中间结果,或者输出临时值。变量的声明也指变量的创建。执行变量声明语句时,系统根据变量的数据类型在内存中开辟相应的存储空间并赋予初始值。变量有一个作用范围,超出它声明语句所在的块就无效。Java实用教程下面看一个使用各种类型变量声明并改变的示例。程序中pi为常量,s1、i1、l1、ch1、f1、d1、b1为全局变量,可以在方法change中发生改变,然后在方法main中输出。而s2、i2、l2、ch2、f2、d2、b2是方法main的局部变量,它们的作用范围只局限于方法main中。【例2.2】测试不同数据类型的变量,程序输出如图2.2所示。源程序代码如下://程序文件名称为SetVariable.javapublicclassSetVariable{//全局变量Java实用教程staticdoublepi=3.141592654;//数学常量staticshorts1;staticinti1;staticlongl1;staticcharch1;staticfloatf1;staticdoubled1;staticbooleanb1;publicstaticvoidmain(Stringargs[]){Java实用教程//局部变量shorts2=35;inti2=-32;longl2=34555L;charch2='A';floatf2=897.89F;doubled2=34.345;booleanb2=false;//输出常量System.out.println("数学常量pi="+pi);//输出局部变量Java实用教程System.out.println("局部变量");System.out.println("短整型变量s2="+s2);System.out.println("整型变量i2="+i2);System.out.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="+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实用教程//方法:修改全局变量的值publicstaticvoidchange(){s1=125;i1=88;l1=987654321L;ch1='B';f1=3.2590F;d1=-1.04E-5;b1=true;}}Java实用教程图2.2变量输出结果Java实用教程2.3运算符和表达式Java常用的运算符分为五类:算术运算符、赋值运算符、关系运算符、布尔逻辑运算符、位运算符。位运算符除了简单的按位操作外,还有移位操作。按位操作返回布尔值。表达式是由常量、变量、对象、方法调用和操作符组成的式子。表达式必须符合一定的规范,才可被系统理解、编译和运行。表达式的值就是对表达式自身运算后得到的结果。根据运算符的不同,表达式相应地分为以下几类:算术表达式、关系表达式、逻辑表达式、赋值表达式,这些都属于数值表达式。Java实用教程2.3.1算术运算符及算术表达式Java中常用的算术运算符如下:+加运算符-减运算符乘运算符/除运算符%取模运算(除运算的余数)++增量运算符--减量运算符Java实用教程【例2.3】测试运算符及表达式,程序输出如图2.3所示。源程序代码如下://程序文件名称为NumberOper.javapublicclassNumberOper{publicstaticvoidmain(Stringargs[]){//变量初始化inta=30;intb=20;//定义结果变量intr1,r2,r3,r4,r5,r6,r7,r8,r9;//计算结果r1=a+b;Java实用教程r2=a-b;r3=ab;r4=a/b;r5=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("ab="+r3);System.out.println("a/b="+r4);System.out.println("a%b="+r5);System.out.println("a++="+r6);System.out.println("b--="+r7);System.out.println("++a="+r8);System.out.println("--b="+r9);}}Java实用教程图2.3程序输出结果Java实用教程2.3.2关系运算符关系运算符用于比较两个数据之间的大小关系,关系运算表达式返回布尔值,即“真”或“假”。Java中的常用关系运算符如下:==等于!=不等于>大于<小于>=大于等于<=小于等于Java实用教程【例2.4】编写程序,测试关系运算符及其表达式,程序输出如图2.4所示。源程序代码如下://程序文件名称为TestRelation.javapublicclassTestRelation{publicstaticvoidmain(Stringargs[]){//变量初始化inta=30;intb=20;//定义结果变量booleanr1,r2,r3,r4,r5,r6;//计算结果Java实用教程r1=a==b;r2=a!=b;r3=a>b;r4=a=b;r6=a<=b;//输出结果System.out.println("a="+a+"b="+b);System.out.println("a==b="+r1);System.out.println("a!=b="+r2);System.out.println("a>b="+r3);System.out.println("a=b="+r5);System.out.println("a<=b="+r6);}}Java实用教程图2.4程序输出结果Java实用教程2.3.3布尔逻辑运算符表2.3布尔运算符及规则运算符含义示例规则!取反!aa为真时,结果为假;a为假时,结果为真&非简洁与a&ba、b都为真时,结果为真;a、b有一个为假时,结果为假非简洁或aba、b有一个为真时,结果为真;a、b都为假时,结果为假^异或a^ba、b不同真假时结果为真;a、b同真或同假时,结果为假&&简洁与a&&ba、b都为真时,结果为真;a、b有一个为假时,结果为假简洁或aba、b有一个为真时,结果为真;a、b都为假时,结果为假Java实用教程图2.3为布尔逻辑运算符及其规则示例等。其中简洁与和简洁或的执行结果分别与非简洁与和非简洁或的执行结果是一致的,不同在于简洁与检测出符号左端的值为假时,不再判断符号右端的值,直接将运算结果置为假;而简洁或与非简洁或的不同在于简洁或检测出符号左端为真时,不再判断符号右端的值,直接将运算结果置为真。例如:Booleana=false;Booleanb=true;a&&b检测到a为假,则无需判断b的值,直接将值置为假;而ba时检测到b为真,则无需判断a的值,直接将值置为真。Java实用教程【例2.5】测试布尔表达式,程序输出结果如图2.5所示。源程序代码如下://程序文件名称为TestLogic.javapublicclassTestLogic{publicstaticvoidmain(Stringargs[]){//变量初始化booleana=false;booleanb=true;//定义结果变量booleanr1,r2,r3,r4,r5,r6;//计算结果Java实用教程r1=!a;r2=a&b;r3=ab;r4=a^b;r5=a&&b;r6=ab;//输出结果System.out.println("a="+a+"b="+b);System.out.println("!a="+r1);System.out.println("a&b="+r2);System.out.println("ab="+r3);System.out.println("a^b="+r4);System.out.println("a&&b="+r5);System.out.println("ab="+r6);}}Java实用教程图2.5程序输出结果Java实用教程2.3.4位运算符Java中的常用位运算符如下:~位求反&按位与按位或^按位异或<<左移>>右移>>>不带符号右移右移运算符对应的表达式为x>>a,运算的结果是操作数x被2的a次方来除,左移运算符对应的表达式为x<>,程序输出结果如图2.6所示。源程序代码如下://程序文件名称为TestBit.javapublicclassTestBit{publicstaticvoidmain(Stringargs[]){//变量初始化inta=36;intb=2;//定义结果变量intr1,r2;Java实用教程//计算结果r1=a>>b;r2=a<>b="+r1);System.out.println("a<>=右移并赋值运算符a>>=ba=a>>b>>>=右移并赋值运算符a>>>=ba=a>>>bJava实用教程2.3.6其它操作符及其表达式三目运算符(?:)相当于条件判断,表达式x?y:z用于判断x是否为真,如果为真,表达式的值为y,否则表达式的值为z。例如:intx=5;inta=(x>3)?5:3;则a的值为5。如果x=2,则a的值为3。Java实用教程对象运算符(instanceof)用来判断一个对象是否属于某个指定的类或其子类的实例,如果是,返回真(true),否则返回假(false)。例如:booleanb=userObjectinstanceofApplet用来判断userObject类是否是Applet类的实例。Java实用教程2.3.7优先级表2.5运算符优先级优先级含义描述运算符结合性1分隔符[]();,2单目运算、字符串运算++--+-~!(类型转换符)右到左3算术乘除运算/%左到右4算术加减运算+-左到右5移位运算<<>>>>>左到右6大小关系运算、类运算<><=>=instanceof左到右7相等关系运算==!=左到右8按位与,非简洁与&左到右9按位异或运算^左到右10按位或,非简洁或左到右11简洁与&&左到右12简洁或左到右13三目条件运算?:右到左14简单、复杂赋值运算==/=%=+=-=<<=>>=>>>=&=^==右到左Java实用教程2.4流程控制流程控制分为三种基本结构:顺序结构、分支结构和循环结构。顺序结构是指命令行顺序执行,这是最常见的一个格式;分支结构是一种选择结构,根据条件的值选择不同的执行流程,可以得到不同的结果。分支结构包括单分支语句(if-else语句)和多分支语句(switch语句);循环结构是指对于一些重复执行的语句,用户指定条件或次数,由机器自动识别执行。循环结构包括次数循环语句(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语句,如果x>10,则输出x的值,并提示结果正确,否则输出x=10,提示结果不正确。程序输出结果如图2.7所示。源程序代码如下://程序文件名称为TestIf.javapublicclassTestIf{//声明全局变量xstaticintx;publicstaticvoidmain(Stringargs[]){x=12;if(x>10){Java实用教程System.out.println("x="+x+"结果正确");}elseSystem.out.println("x=10"+"结果不正确");change();System.out.println("修改x的值之后");if(x>10){System.out.println("x="+x+"结果正确");}elseSystem.out.println("x=10"+"结果不正确");}Java实用教程//change方法:修改x的值publicstaticvoidchange(){x=5;}}Java实用教程图2.7程序输出结果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是可能出现的值。(4)不同的case分支对应着不同的语句或块序列。(5)break表示跳出这一分支。Java实用教程【例2.8】测试switch语句,当x=1、2、3时,分别打印1、2、3,x不为这三个值时,打印x的值。程序输出结果如图2.8所示。源程序代码如下://程序文件名称为TestSwitch.javapublicclassTestSwitch{publicstaticvoidmain(Stringargs[])//声明变量xintx;x=12;Java实用教程System.out.println("x=12时打印的值");choose(x);x=3;System.out.println("x=3时打印的值");choose(x);}//choose方法:switch语句结构publicstaticvoidchoose(intx){switch(x){Java实用教程case1:System.out.println(1);break;case2:System.out.println(2);break;case3:System.out.println(3);break;default:System.out.println(x);}}}Java实用教程图2.8程序输出结果Java实用教程2.4.2for循环语句for循环语句实现已知次数的循环,其基本格式为:for(初始化表达式;测试表达式;步长){语句或块;}Java实用教程其执行顺序如下:(1)首先运行初始化表达式。(2)然后计算测试表达式,如果表达式为true,执行语句或块;如果表达式为false,退出for循环。(3)最后执行步长。Java实用教程【例2.9】用for循环统计1~100(包括100)之间数的总和。程序输出结果如图2.9所示。源程序代码如下://程序文件名称为TestFor.javapublicclassTestFor{publicstaticvoidmain(Stringargs[]){intsum=0;for(inti=1;i<=100;i++)sum+=i;System.out.println("1到100(包括100)的数的总和为:"+sum);}}Java实用教程图2.9程序输出结果Java实用教程2.4.3while循环语句while循环语句实现受条件控制的循环,其基本格式为:while(布尔表达式){语句或块;}当布尔表达式为true时,执行语句或块,否则跳出while循环。Java实用教程上面for循环语句的例子改为while语句后如下所示:intsum=0;inti=1;while(i<=100){sum+=i;i++;}System.out.println("1到100(包括100)的数的总和为:"+sum)Java实用教程2.4.4do语句do语句实现受条件控制的循环,其基本格式为:do{语句或块;}while(布尔表达式)Java实用教程先执行语句或块,然后再判断布尔表达式。与while语句不同,当布尔表达式一次都不为true时,while语句一开始判断就跳出循环,不执行语句或块,而在do语句中则要执行一次。上面那个例子改为do循环为:intsum=0;inti=1;do{sum+=i;i++;}while(i<=100);System.out.println("1到100(包括100)的数的总和为:"+sum);Java实用教程2.5数组的使用2.5.1数组声明数组的定义如下:(1)首先是一个对象。(2)存放相同的数据类型,可以是原始数据类型或类类型。(3)所有的数组下标默认从0开始,而且访问时不可超出定义的上限,否则会产生越界错误。Java实用教程数组声明时实际是创建一个引用,通过代表引用的这个名字来引用数组。数组声明格式如下:数据类型标识符[]例如:inta[];//声明一个数据类型为整型的数组apencilb[];//声明一个数据类型为pencil类的数组bJava实用教程2.5.2创建数组由于数组是一个对象,所以可以使用关键字new来创建一个数组,例如:a=newint[10];//创建存储10个整型数据的数组ab=newpencil[20];//创建存储20个pencil类数据的数组b数组创建时,每个元素都按它所存放数据类型的缺省值被初始化,如上面数组a的值被初始化为0,也可以进行显式初始化。在Java编程语言中,为了保证系统的安全,所有的变量在使用之前必须是初始化的,如果未初始化,编译时会提示出错。有两种初始化数组的方式,分别如下:Java实用教程(1)创建数组后,对每个元素进行赋值。a[0]=5;a[1]=4;...a[9]=10;(2)直接在声明的时候就说明其值,例如:inta[]={4,5,1,3,4,20,2};说明了一个长度为7的一维数组。Java实用教程【例2.10】编写程序测试数组,程序输出结果如图2.10所示。源程序代码如下://程序文件名称为TestArray.javapublicclassTestArray{publicstaticvoidmain(Stringargs[]){//声明数组inta[];charb[];//创建数组Java实用教程a=newint[3];b=newchar[2];//数组初始化for(inti=0;i<3;i++){a[i]=i3;}b[0]='a';b[1]='b';//快速初始化数组intc[]={0,13,23};//输出结果System.out.print("数组a\n");Java实用教程for(inti=0;i<2;i++){System.out.print(b[i]+"");}System.out.print("\n数组c\n");for(inti=0;i<3;i++){System.out.print(c[i]+"");}}}Java实用教程图2.10程序输出结果Java实用教程习题1.给出下列表达式的值。(1)3++4<<2^-8(2)"abc"&1238<<2(3)36>>24&&48<<8/4+2(4)24&&0<24%22.编写程序,统计课程编号为1001、1002、2001和3001的平均成绩并输出。学生成绩表如图2.11所示。【每个课程编号的成绩用数组存储,读取时循环操作】Java实用教程图2.11习题2.2的成绩表Java实用教程3.根据上题得出的考生平均成绩进行判断,如果在90分以上,屏幕上输出“课程编号为XXXX的考生平均成绩为优”;在80~90分之间输出“课程编号为XXXX的考生平均成绩为良”;在70~80分之间输出“课程编号为XXXX的考生平均成绩为中”,在60~70分之间输出“课程编号为XXXX的考生平均成绩为及格”;60分以下输出“课程编号为XXXX的考生平均成绩为不及格”。4.编写程序,用数组实现乘法小九九的存储和输出。【提示:采用多个一维数组。】Java实用教程第3章类和接口3.1类3.2接口3.3常用数据结构及类习题Java实用教程3.1类3.1.1类的定义和声明Java编程语言是面向对象的,处理的最小的完整单元为对象。而现实生活中具有共同特性的对象的抽象就称之为类。类由类声明和类体构成,类体又由变量和方法构成。下面给出一个例子来看一下类的构成。【例3.1】自定义一个apple类,在主类SetApple中创建实例并调用方法,输出结果如图3.1所示。源程序代码如下:Java实用教程//程序文件名为SetApple.javapublicclassSetApple{publicstaticvoidmain(String[]args){applea=newapple();//创建apple类a.appleweight=0.5;//实例变量赋值System.out.println("苹果的重量为1两");System.out.println(a.bite());//调用实例方法a.appleweight=5;System.out.println("苹果的重量为5两");System.out.println(a.bite());}}Java实用教程//自定义类classapple{//属性longapplecolor;//对应苹果的颜色doubleappleweight;//苹果的重量booleaneatup;//是否吃完//类方法publicbooleanbite(){if(appleweight<1){System.out.println("苹果已经吃完了!哈哈");eatup=true;}Java实用教程else{System.out.println("苹果吃不下了!:(");eatup=false;}returneatup;}}Java实用教程图3.1自定义类的应用Java实用教程1.类声明的基本格式访问说明符class类名extends超类名implements接口名其中:(1)访问说明符为public或者缺省。public用来声明该类为公有类,可以被别的对象访问。声明为公有的类存储的文件名为类名。(2)类名:用户自定义的标识符,用来标志这个类的引用。(3)超类名:是指已经存在的类,可以是用户已经定义的,也可以是系统类。(4)接口名:即后面讲到的接口。Java实用教程例如:publicclassHelloAppletextendsApplet访问说明符为public,类名HelloApplet,扩展类为JDK包自带的java.applet.Applet类。由于public的存在,所以文件名必须存为HelloApplet.java,同类名保持一致。Java实用教程2.类体类体包括成员变量和方法。(1)成员变量:指类的一些属性定义,标志类的静态特征,它的基本格式如下:访问说明符数据类型变量名其中:●访问说明符有public、private和protected三种:public:省略时默认为公有类型,可以由外部对象进行访问。private:私有类型,只允许在类内部的方法中使用,若从外部访问,必须通过构造函数间接进行。Protected:受保护类型,子类访问受到限制。Java实用教程(2)方法:是类的操作定义,标志类的动态特征,它的基本格式如下:●访问说明符数据类型方法名(数据类型1变量名1,数据类型2变量名2)其中:●访问说明符为public、private和protected,其使用方法与成员变量访问说明符的使用方法一致。●数据类型:包括基本数据类型和用户自定义的扩展类型。●数据类型为参数。Java实用教程3.创建类的实例使用关键字new进行创建,例如:HelloApplethp=newHelloApplet();例3.1中,自定义类apple,访问标识符缺省,定义三个属性:longapplecolor;//对应苹果的颜色doubleappleweight;//苹果的重量booleaneatup;//是否吃完Java实用教程一个方法为:publicbooleanbite()//类方法{...}公有类SetApplet中引用自定义类,首先创建类的实例:applea=newapple();其次赋初值:a.appleweight=0.5;//实例变量赋值最后调用它的方法:System.out.println(a.bite());//调用实例方法Java实用教程3.1.2类的单继承性Java编程语言中允许用extends关键字从一个类扩展出一个新类,新类继承超类的成员变量和方法,并可以覆盖方法。【例3.2】测试类的单继承性,程序输出结果如图3.2所示。源程序代码如下://程序文件名TestExtend.javapublicclassTestExtendextendsEmployee{publicstaticvoidmain(String[]args){System.out.println("覆盖的方法调用:"+getSalary("王一",500));Java实用教程System.out.println("继承的方法调用:"+getSalary2("王一",500));System.out.println("覆盖的方法调用:"+getSalary("王飞",10000));System.out.println(“继承的方法调用:”+getSalary2(“王飞",10000));}publicstaticStringgetSalary(Stringname,intsalary){Stringstr;if(salary>5000)str="名字:"+name+"Salary:"+salary;elseJava实用教程returnstr;}};classEmployee{publicStringname;//名字publicintsalary;//薪水publicstaticStringgetSalary(Stringname,intsalary){Stringstr;str="名字:"+name+"Salary:"+salary;returnstr;}Java实用教程publicstaticStringgetSalary2(Stringname,intsalary){Stringstr;str="名字:"+name+"Salary:"+salary;returnstr;}};Java实用教程程序中定义了父类Employee类,它有两个方法getSalary和getSalary2,方法体的实现都是一致的,都为输出名字和薪水的值。在TextExtend主类中覆盖了getSalary方法,方法体重新定义为薪水低于5000时并不输出薪水的值而是输出“低于5000”,用于和继承的getSalary2方法进行比较。由图3.2可以看出覆盖的方法按主程序中重定义的方法调用,而继承的方法直接调用父类中的方法。Java实用教程图3.2测试单继承性程序的输出结果Java实用教程3.1.3特殊变量类中有两个特殊变量super和this。1.super类声明中用关键字extends扩展了其超类之后,super用在扩展类中引用其超类中的成员变量。【例3.3】使用super变量,输出结果如图3.3所示。源程序代码如下://程序文件名为UseSuper.javapublicclassUseSuper{Java实用教程publicstaticvoidmain(String[]args){Managerm=newManager();m.name="王飞";m.salary=10000;m.department="业务部";System.out.println(m.getSalary());}}classEmployee{Java实用教程publicStringname;//名字publicintsalary;//薪水//方法publicStringgetSalary(){Stringstr;str="名字:"+name+"\nSalary:"+salary;returnstr;}}classManagerextendsEmployeeJava实用教程{publicStringdepartment;//部门//方法publicStringgetSalary(){//使用super变量调用超类的方法returnsuper.getSalary()+"\nDepartment:"+department;}}Java实用教程图3.3测试super变量的输出Java实用教程2.thisthis变量指向当前对象或实例。str="名字:"+name+"\nSalary:"+salary;上例中的语句可以换成下面的语句。str="名字:"+this.name+"\nSalary:"+this.salary;这两者是等同的,因为在Java编程语言中,系统自动将this关键字与当前对象的变量相关联。但有一种情况例外,就是当在某些完全分离的类中调用一个方法并将当前对象的一个引用作为参数传递时。例如:Dayd=newDay(this);Java实用教程3.1.4构造函数类中的构造函数用来初始化一个类。构造函数为公有类型,无返回值,用来从类实例中访问类时初始化此类的私有变量。【例3.4】基于例3.3将公有变量改成私有变量之后,增加两个构造函数,访问通过外部调用构造函数实现初始化赋值,得到如图3.3所示的结果。//程序文件名为UseConstruct.javapublicclassUseConstruct{publicstaticvoidmain(String[]args){Java实用教程Managerm=newManager("王飞",10000,"业务部");//初始化赋值System.out.println(m.getSalary());}}classEmployee{privateStringname;//名字privateintsalary;//薪水//构造函数publicEmployee(String_name,int_salary){Java实用教程name=_name;salary=_salary;}publicStringgetSalary(){Stringstr;str="名字:"+name+"\nSalary:"+salary;returnstr;}}classManagerextendsEmployee{privateStringdepartment;Java实用教程//构造函数publicManager(String_name,int_salary,String_department){super(_name,_salary);department=_department;}publicStringgetSalary(){returnsuper.getSalary()+"\nDepartment:"+department;}}Java实用教程3.1.5包计算机操作系统使用文件夹或者目录来存放相关或者同类的文档,在Java编程语言中,提供了一个包的概念来组织相关的类。包在物理上就是一个文件夹,逻辑上代表一个分类概念。包就是指一组类。例如一个名叫Company的包,可以包含一组类,如Employee(雇员)、Manager(管理者)和Department(部门)等。声明包的基本格式如下:Package包名;Java实用教程其中:Package为关键字,包名为标识符。使用包时的注意事项如下:(1)Package语句要作为程序非注释语句的第一行语句。(2)包内的类名惟一。(3)引用包中的类时,使用import语句。import语句的基本格式为import包名.类名,其中import为关键字,包名和类名之间用圆点(.)隔开。Java实用教程【例3.5】编写程序测试包,先建立一个Company文件夹,然后建立名为Manager.java的类文件。源程序代码如下://程序文件名为Manager.javapackageCompany;//声明包名CompanyclassEmployee{publicStringname;//名字publicintsalary;//薪水publicStringgetSalary(){Java实用教程Stringstr;str="名字:"+name+"\nSalary:"+salary;returnstr;}}publicclassManagerextendsEmployee{publicStringdepartment;//部门publicStringgetSalary(){returnsuper.getSalary()+"\nDepartment:"+department;}}Java实用教程对此文件进行编译,生成类文件Manager.class。在原目录建立源程序文件UsePackage.java。源程序代码如下://程序文件名UsePackage.javaimportCompany.Manager;//引入包中的类publicclassUsePackage{publicstaticvoidmain(String[]args){Managerm=newManager();m.name="王飞";m.salary=10000;m.department="业务部";System.out.println(m.getSalary());}}Java实用教程编译后,在命令提示符状态下运行,输出结果如图3.4所示。从图3.4中可以看出首先进入Company目录,编译Manager.java文件,然后返回上层目录,编译UsePackage.java文件,最后执行UsePackage类文件,输出正确的结果。Java实用教程图3.4测试包的输出结果Java实用教程3.2接口Java编程语言中禁止多继承属性,但可以通过接口来帮助类扩展方法。接口中可以定义大量的常量和方法,但其中的方法只是一种声明,没有具体的实现,使用接口的类自己实现这些方法。接口与类的不同在于:(1)没有变量的声明,但可以定义常量。(2)只有方法的声明,没有方法的实现。接口声明的基本格式如下:publicinterface接口名extends接口列表Java实用教程【例3.6】测试接口,定义接口文件Product.java,定义了两个常量,声明了一个方法。接口文件如下://程序文件名Product.javapublicinterfaceProduct{staticfinalStringMAKER="计算机制造厂";staticfinalStringADDRESS="上海";publicintgetPrice();}Java实用教程使用接口的源文件代码如下://程序文件名UseInterface.javapublicclassUseInterface{publicstaticvoidmain(String[]args){Computerp=newComputer();System.out.print(p.ADDRESS+p.MAKER);System.out.println("计算机的价格:"+p.getPrice()+"万元");}}Java实用教程classComputerimplementsProduct{publicintgetPrice(){return1;}}Java实用教程首先编译接口文件“javacProduct.java”,然后编译使用这个接口的类文件“javac.UseInterface.java”,最后执行类“javaUseInterface”,输出结果如图3.5所示。图3.5测试接口的输出结果Java实用教程3.3常用数据结构及类3.3.1Vector类Vector类似于一个数组,但与数组相比在使用上有以下两个优点。(1)使用的时候无需声明上限,随着元素的增加,Vector的长度会自动增加。(2)Vector提供额外的方法来增加、删除元素,比数组操作高效。Vector类有三个构造函数,分别如下:publicVector();该方法创建一个空的Vector。Java实用教程publicVector(intinitialCapacity);该方法创建一个初始长度为initialCapacity的Vector。publicVector(intinitialCapacity,intcapacityIncrement);该方法创建一个初始长度为initialCapacity的Vector,当向量需要增长时,增加capacityIncrement个元素。Java实用教程(1)Vector类中添加、删除对象的方法如下:publicvoidadd(intindex,Objectelement)在index位置添加对象element。publicbooleanadd(Objecto)在Vector的末尾添加对象o。publicObjectremove(intindex)删除index位置的对象,后面的对象依次前提。Java实用教程(2)Vector类中访问、修改对象的方法如下:publicObjectget(intindex)返回index位置对象。publicObjectset(intindex,Objectelement)修改index位置的对象为element。Java实用教程(3)其它方法:publicStringtoString()将元素转换成字符串。publicintsize()返回对象的长度。Java实用教程【例3.7】操作Vector对象,进行元素的添加、插入、修改和删除。程序输出结果如图3.6所示。源程序代码如下://程序文件名为UseVector.javaimportjava.util.Vector;//引入JDK的Vector类publicclassUseVector{publicstaticvoidmain(String[]args){Java实用教程VectorvScore=newVector();vScore.add("86");//添加元素vScore.add("98");//添加元素vScore.add(1,"99");//插入元素//输出结果for(intI=0;I,浏览器中执行Applet的步骤如下:(1)浏览器请求HTML页面。(2)读HTML页面的过程中发现标签,然后继续向服务器请求标签中声明的类文件。(3)浏览器获取该类文件。(4)字节码验证这个类是否合法。(5)如果合法就开始执行类文件。Java实用教程有时可能需要载入多个类文件,直到将所有所需的类文件下载完毕为止。为上面的UseApplet.class类写一个最简单的网页UseApplet.html: Java实用教程图4.2Applet输出时间Java实用教程图4.3网页下显示输出时间的AppletJava实用教程4.2.2参数设置在HTML页面中嵌入Applet类文件时,可以在标签中设置属性以控制Applet类文件的外观显示,也可以传递一些用户自定义属性。嵌入的格式为:...Java实用教程其中:(1)标签内为Applet的信息。(2)标记在之间进行设置,然后由Applet自带的方法获取。(3)标记有两个自己的属性:name和value。例如:(4)attribute1和attribute2的属性设置如表4.1所示。Java实用教程表4.1属性设置及其描述属性列表放置属性描述code使用的Applet类文件的名字codebase基目录的URL,Applet的类文件都存放在这里heightApplet网页上占据的垂直像素高度widthApplet网页上占据的水平像素宽度vspaceApplet和其它HTML语句之间的垂直距离hspaceApplet和其它HTML语句之间的水平距离align与页中其余部分的对齐方式alt不显示Applet时,显示的实际文本archive浏览器预加载的其它文档资源的列表attribute1object代替code属性出现,将Applet类文件作为一个对象调用nameApplet程序中所需参数名Attribute2valueApplet程序中所需参数传递的值Java实用教程其中,code属性是必须的,height和width属性用来设置高度和宽度,如果都为0,那么Applet将隐藏。对于例4.1中UseApplet.html,如果有那么说明网页加载的类名为UseApplet.class,类显示的高度为200像素点,宽度为300像素点。表4.1中列出的attibute1属性为定义的属性。用户还可以根据Applet程序的需要,传递一些程序自身属性,这些属性通过attribute2中name属性给出所需参数的名,value属性给出所需参数的值。publicStringgetParameter(Stringname)Java实用教程【例4.2】基于例4.1,在加载类的网页上设置一个用户名,使得Applet输出为“XXX,你好,当前时间为:(具体时间)”,如图4.4所示。源程序代码如下://程序文件名UsePara.javaimportjava.awt.;importjava.applet.Applet;importjava.util.Date;publicclassUseParaextendsApplet{StringstrTime=newString();StringstrUser=newString();publicvoidinit(){Java实用教程//得到网页的参数:用户名strUser=getParameter("USER");}publicvoidstart(){Dated=newDate();strTime=d.toString();repaint();}publicvoidpaint(Graphicsg){g.setColor(Color.red);g.drawString(strUser+"你好,当前时间为:"+strTime,20,30);}};Java实用教程在UseApplet.html中添加一个用户参数设置:使修改后的网页程序如下: Java实用教程图4.4网页设置参数后的Applet输出Java实用教程放在浏览器中查看时,显示效果如图4.5所示。图4.5浏览器中查看获取网页参数的Applet输出Java实用教程4.2.3生命周期Applet的生命周期是指Applet存在的时间,即某些方法还在被调用的时间。根据Applet的四个方法init()、start()、stop()、destroy(),可以得出Applet的生命周期,如图4.6所示。ÖØмÓÔØä¯ÀÀÆ÷»ò¸Ä±ää¯ÀÀÆ÷³ß´ç»ò·µ»ØÍøÒ³À뿪ÍøÒ³Í˳öä¯ÀÀÆ÷³õʼ»¯Æô¶¯Í£Ö¹³·Ïû图4.6Applet的生命周期Java实用教程4.3载入图片在java.applet包中存在一个接口AppletStub。当一个Applet创建之后,一个AppletStub使用setStub方法附加到Applet上,这个Stub用来充当Applet和浏览器环境之间的接口。在这个接口中一个重要的方法:publicURLgetDocumentBase()该方法返回的是Applet类文件所在网页的网络路径。例如,如果一个Applet类文件嵌入在下面网页中http://java.sun.com/products/jdk/1.2/index.html那么返回的路径为http://java.sun.com/products/jdk/1.2/Java实用教程通过这个网络路径可以得到图片,从而由Applet类载入,载入图片的方法为:publicImagegetImage(URLurl,Stringname)其中:(1)url给出图片所在的网路路径。(2)name给出图片的名字。例如:url路径可以为http://java.sun.com/products/jdk/1.2/,而name可以为路径下的图片index_01.gif。Java实用教程【例4.3】编写Applet,载入Applet类文件所在路径下的图片index_01.gif,然后如图4.7所示显示图片。源程序代码如下://程序文件名UseImage.javaimportjava.awt.;importjava.applet.Applet;importjava.net.;publicclassUseImageextendsApplet{//定义图像对象ImagetestImage;publicvoidinit(){Java实用教程//得到图片testImage=getImage(getDocumentBase(),"index_01.gif");}publicvoidpaint(Graphicsg){g.drawImage(testImage,0,0,this);}}载入UseImage.class类的UseImage.html文件如下: Java实用教程图4.7Applet载入图片显示Java实用教程4.4载入声音Applet类提供一个用于载入声音的方法,即publicAudioClipgetAudioClip(URLurl,Stringname)该方法返回由url和name决定的AudioClip对象。其中:(1)url:音频剪辑的绝对URL地址;(2)name:相对于上面的url,为音频剪辑的相对地址,通常指名字。Java实用教程【例4.4】编写载入声音的Applet。源程序代码如下://程序文件名UseAudio.javaimportjava.awt.;importjava.applet.Applet;publicclassUseAudioextendsApplet{publicvoidinit(){}publicvoidstart(){//播放Applet所在目录下的tiger.au声音文件getAudioClip(getDocumentBase(),"tiger.au").play();Java实用教程}};载入类的HTML文件如下: var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?da79d620512880b98e7126c2ef50ea32"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); 在浏览器加载或者appletviewer命令启动时可以听见老虎的叫声,但必须保证tiger.au在UseAudio.class类文件所在Java实用教程4.5Applet控制浏览器环境java.applet包中提供一个接口AppletContext,对应着Applet的环境,主要指包含Applet的网页文档等,在这个接口内有两个重要方法:pubilcvoidshowDocument(URLurl)浏览器下载Applet时,showDocument可以将当前Applet页面用于显示url网址的内容。url给出页面的绝对网络路径。publicvoidshowDocument(URLurl,Stringtarget)target可以表明url显示的位置,有四种情况,如表4.2所示。Java实用教程表4.2target取值target选项描述_self将url表示的页面显示在Applet框架中_parent将url表示的页面显示在父框架中,如果不存在,情况如同_self_top将url表示的页面显示在Applet窗口的顶层框架,如果不存在,情况如同_self_blank将url表示的页面显示在新窗口中publicvoidshowStatus(Stringstatus)字符串status显示在状态栏中,告知用户当前类文件运行中的状态。Java实用教程【例4.5】编写Applet,在状态栏显示鼠标单击Applet的次数,结果如图4.8所示。源程序代码如下://程序文件名ShowStatus.javaimportjava.applet.;importjava.applet.Applet;importjava.awt.event.;publicclassShowStatusextendsApplet{intcount=0;publicvoidinit()Java实用教程{}publicbooleanmouseClicked(MouseEvente){count++;getAppletContext().showStatus("你好,你已经点击了"+count+"次了!");returntrue;}};Java实用教程图4.8状态栏显示单击次数信息Java实用教程【例4.6】编写Applet,在一个框架中显示不同来源的网页信息,如图4.9所示。左框架为西安交通大学首页,右框架为新浪网首页。源程序代码如下://程序文件名ShowHtml.javaimportjava.applet.;importjava.applet.Applet;importjava.net.URL;publicclassShowHtmlextendsApplet{publicvoidinit(){}Java实用教程publicvoidstart(){try{//创建URL对象URLurlName=newURL("http://www.xjtu.edu.cn");//在左框架显示网页getAppletContext().showDocument(urlName,"left");urlName=newURL("http://www.sina.com.cn");//右框架显示网页getAppletContext().showDocument(urlName,"right");}Java实用教程catch(MalformedURLExceptione){System.out.println(e.getMessage());}}}载入Applet的网页Head.html的代码如下:Java实用教程

这是一个框架网页,上面的框架隐藏载入applet类文件,由applet控制左框架显示西安交通大学的主页,右框架显示新浪网的主页。 装配的框架网页ShowHtml.html的源代码如下,可以看见其中框架名字左边的为left而右边的为right。Java实用教程Java实用教程图4.9框架网页显示Java实用教程4.6服务器下配置Applet文件由于Applet文件是客户端浏览器从服务器端下载的HTML网页,所以将文件配置到服务器端,由客户进行访问。本机中使用的服务器为Tomcat4.0,安装成功后重启动,则服务器开始运转,在浏览器的网址栏键入http://192.100.100.43:8080/index.html,如果出现如图4.10所示的Tomcat主网页,则证明服务器测试正常。Java实用教程图4.10Tomcat主页Java实用教程配置自己的文件时,推荐在安装目录D:\ApacheTomcat4.0\webapps\ROOT下建立自己的文件夹,这样有利于管理。本书作者在此文件夹下建立user目录,以为载入图片的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使用插件载入AppletJava插件(Plug-in)扩展了网络浏览器的功能,使得无论在哪个浏览器(IE浏览器或者Netscape浏览器)下,JavaApplet可在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)“指定文件”为要转换的文件。(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.12HtmlConverter工具界面Java实用教程其中codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_0_01-win.cab#Version=1,4,0,10">表示如果客户端浏览器不存在此插件,可以从codebase指定的网址下载,由上述语句行可以看出HtmlConverter生成的插件文件的插件下载地址为Sun公司的网站。如果本机上放置了插件的安装程序,那么此处可以改为从本机下载,以加快下载速度。如果在网站上发布你的Applet的网页,建议使用插件方式载入Applet,可以与多种浏览器兼容。Java实用教程4.8JAR文件4.8.1操作JAR文件在JDK的安装目录的bin子目录下有一个jar.exe文件,这就是JAR文件的操作工具,用它及一系列选项来实现对JAR文件的操作。jar命令的格式如下:jar{ctxu}[vfm0M][jar-文件][manifest-文件][-C目录]文件名...Java实用教程其中:(1)ctxu四者必选其一,各选项的含义如下:-c创建新的存档;-t列出存档内容的列表;-x展开存档中命名的(或所有的)文件;-u更新已存在的存档。Java实用教程(2)vfm0M为可选项,各选项的含义如下:-v生成详细输出到标准输出上;-f指定存档文件名;-m包含来自标明文件的标明信息;-0只存储方式,未用ZIP压缩格式;-M不产生所有项的清单(manifest)文件;-C改变到指定的目录,并且包含下列文件。Java实用教程(3)清单(manifest)文件名和存档文件名都需要指定,指定的顺序依照命令行中“m”和“f”标志的顺序。例如:①将两个class文件存档到一个名为“classes.jar”的存档文件中:jarcvfclasses.jarFoo.classBar.class②用一个存在的清单(manifest)文件“mymanifest”将foo/目录下的所有文件存档到一个名为“classes.jar”的存档文件中:jarcvfmclasses.jarmymanifest-Cfoo/.对JAR文件常用的操作有三种:创建JAR文件、列出Java实用教程1.创建JAR文件jarcvfUseImage.jarUseImage.classindex_01.gif当用JAR工具创建新的档案时,自动增加一个声明文件到文档中。如果用户需要创建自己的声明文件时,则指定m选项。可以看到本目录下多了一个UseImage.jar文件。创建JAR文件的过程如图4.13所示。图4.13创建JAR文件Java实用教程2.列出JAR文件的内容jartvfUseImage.jar执行命令后列出JAR文件中的内容,如图4.14所示。图4.14列出JAR文件Java实用教程3.抽取JAR文件jarxvfUseImage.jar抽取JAR文件是将JAR中包含的类以及相关文件逐一恢复。在E:\_Work\Java\sample目录下建立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:\ApacheTomcat4.0\webapps\ROOT\user\UseImage.html文件代码改为: Java实用教程4.9Applet和应用程序【例4.7】修改例4.1的Applet,使得它可以从命令提示符状态下访问。(1)基于例4.1的UseApplet添加一个main方法如下:publicstaticvoidmain(String[]args){//创建一个框架Framef=newFrame("时间");//关闭窗口时退出系统f.addWindowListener(newWindowAdapter(){Java实用教程publicvoidwindowClosing(WindowEventevt){System.exit(0);}});//创建一个AppletApp对象AppletAppa=newAppletApp();//将对象载入框架f.add("Center",a);//设置框架大小f.setSize(300,200);//显示框架Java实用教程f.show();//初始化对象a.init();//启动对象a.start();}Java实用教程(2)修改后的源程序代码如下://程序文件名AppletApp.javaimportjava.awt.;importjava.awt.event.;importjava.applet.Applet;importjava.util.Date;publicclassAppletAppextendsApplet{StringstrTime=newString();publicvoidinit(){}Java实用教程publicvoidstart(){Dated=newDate();strTime=d.toString();repaint();}publicvoidpaint(Graphicsg){g.drawString("当前时间为:"+strTime,20,30);}publicstaticvoidmain(String[]args){Java实用教程//创建一个框架Framef=newFrame("时间");//关闭窗口时退出系统f.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEventevt){System.exit(0);}});//创建一个AppletApp对象AppletAppa=newAppletApp();Java实用教程a.init();//将对象载入框架f.add("Center",a);f.setSize(200,400);f.show();a.start();}};Java实用教程(3)编译通过并生成UseApplet.class类后,在命令提示符状态下键入“javaUseApplet”,得到如图4.2所示的时间输出界面。Java实用教程【例4.8】修改例4.2,在命令提示符状态下输入用户名参数,使得可以在命令提示符状态下进行访问。(1)从命令行状态输入用户名参数,应用程序的读取如下:if(args.length<1){System.out.println("缺少用户参数");System.exit(0);}elsestrUser=newString(args[0]);Java实用教程(2)添加一个变量staticbooleaninApplet=true;用于控制取参数的方式,如果以应用程序调用,则从命令行取参数;如果是载入Applet,则从网页中取参数。Java实用教程(3)源程序代码如下://程序文件名AppPara.javaimportjava.awt.;importjava.awt.event.;importjava.applet.Applet;importjava.util.Date;publicclassAppParaextendsApplet{StringstrTime=newString();staticStringstrUser=newString();staticbooleaninApplet=true;publicvoidinit(){Java实用教程//如果从Applet载入,从网页得到参数if(inApplet)strUser=getParameter("USER");}publicvoidstart(){Dated=newDate();strTime=d.toString();repaint();}publicvoidpaint(Graphicsg){Java实用教程g.setColor(Color.red);g.drawString(strUser+"你好,当前时间为:"+strTime,20,30)}publicstaticvoidmain(String[]args){inApplet=false;//如果从命令行提示符状态进入,获取参数if(args.length<1){System.out.println("缺少用户参数");System.exit(0);}elseJava实用教程strUser=newString(args[0]);//创建一个框架Framef=newFrame("时间");//关闭窗口时退出系统f.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEventevt){System.exit(0);}});//创建一个AppletApp对象AppParaa=newAppPara();Java实用教程//初始化a.init();//将对象载入框架f.add("Center",a);//设置框架大小f.setSize(400,200);//显示框架f.show();//启动对象a.start();}}Java实用教程(4)在命令提示符状态键入命令“javaAppPara王飞”后按回车键,弹出如图4.5所示的界面。Java实用教程习题1.编写Applet,载入图片的同时响起音乐。2.将上题的Applet类、图片文件、音乐文件进行压缩并生成JAR文件,然后载入运行。Java实用教程3.编写程序,既可用作Applet,又可用作应用程序,在出现的界面中显示下面的内容,括号内表示显示的颜色。特点:(蓝色显示)(1)跨平台性(以下均为红色显示)(2)面向对象(3)安全性(4)多线程(5)简单易用Java实用教程4.在上题的基础上,输入参数“Java语言”,使得显示内容如下所示,要求既可以从命令行输入,也可以从网页内输入。Java语言特点:(1)跨平台性(2)面向对象(3)安全性(4)多线程(5)简单易用Java实用教程第5章Java图形处理5.1Java图形5.2Paint方法、Update方法和Repaint方法5.3Graphics类5.4Color类5.5Graphics2D类习题Java实用教程5.1Java图形抽象窗口化工具(AWT)为图形用户界面编程提供API编程接口,使得Java可以提供较好的图形用户界面。AWT把图形处理分为两个层次:一是处理原始图形,这一层较原始,图形直接以点、线和面的形式画到界面上;二是提供大量组件,实现可定制的图形用户界面。本章主要讨论如何在界面上画图形及所画图形的特征。Java编程语言中的图形坐标系统不同于数学中的坐标系,屏幕左上角为(0,0),右下角为屏幕水平向右和垂直向下增长的像素数。Java实用教程5.2Paint方法、Update方法和Repaint方法1.Paint方法publicvoidpaint(Graphicsg)以画布为参数,在画布上执行画图方法。在Applet中,不显式地调用paint方法。2.Repaint方法Applet重画时系统自动调用paint方法。3.Update方法publicvoidupdate(Graphicsg)更新容器,向Repaint发出刷新小应用程序的信号,缺省的Update方法清除Applet画图区并调用Paint方法。Java实用教程5.3Graphics类Graphics类是所有图形上下文的抽象基类,允许应用程序在各种设备上实现组件的画图。图形对象封装了Java支持的基本渲染操作的状态信息,包括画图的组件对象、渲染区域的坐标(coordinates)、区域(clip)、颜色(color)、字体(font)、画图模式等。Graphics类提供画各种图形的方法,其中包括线、圆和椭圆、矩形和多边形、图像以及各种字体的文本等。这些方法具体如下:publicabstractvoidclipRect(intx,inty,intwidth,intheight)指定的区域切分。Java实用教程publicabstractvoiddrawLine(intx1,inty1,intx2,inty2)使用当前颜色,在点(x1,y1)和(x2,y2)之间画线。publicabstractvoiddrawOval(intx,inty,intwidth,intheight)画椭圆。publicabstractvoidfillOval(intx,inty,intwidth,intheight)画实心椭圆。publicabstractvoiddrawPolygon(int[]xPoints,int[]yPoints,intnPoints)画x和y坐标定义的多边形。Java实用教程publicvoiddrawRect(intx,inty,intwidth,intheight)画矩形。publicvoiddrawRect(intx,inty,intwidth,intheight)画实心矩形。publicabstractvoiddrawRoundRect(intx,inty,intwidth,intheight,intarcWidth,intarcHeight)使用当前颜色画圆角矩形。publicabstractvoiddrawString(Stringstr,intx,inty)使用当前字体和颜色画字符串str。Java实用教程publicabstractvoidsetColor(Colorc)设置图形上下文的当前颜色。publicabstractvoidsetPaintMode()设置画模式。publicabstractbooleandrawImage(Imageimg,intx,inty,ImageObserverobserver)画特定图。publicabstractvoidsetFont(Fontfont)设置特定的font字体。使用时首先得到font对象的一个实例,Font类常用构造函数为:publicFont(Stringname,intstyle,intsize)Java实用教程通过指定的name、style和size创建字体实例。name指字体名,像“隶书”、“TimesRoman”等,字体风格为粗体、斜体,size指字号大小。例如:Fontf=newFont("TimesRoman",Font.BOLD+Font.ITALIC,12);创建了具有粗斜体风格的12磅的TimesRoman字体。Java实用教程【例5.1】设置Graphics对象画图,显示结果如图5.1所示。源程序代码如下://程序文件名SimpleGUI.javaimportjava.awt.;importjava.applet.;publicclassSimpleGUIextendsApplet{ImagesamImage;publicvoidinit(){samImage=getImage(getDocumentBase(),"sample.gif");Java实用教程}publicvoidpaint(Graphicsg){//g.clipRect(50,50,180,180);//画线g.drawLine(0,0,20,30);//输出字符串g.drawString("图形显示",100,30);//设置颜色Colorc=newColor(255,200,0);g.setColor(c);//设置字体Java实用教程Fontf=newFont("TimesRoman",Font.BOLD+Font.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(150,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实用教程//多边形intxC[]={242,260,254,297,242};intyC[]={240,243,290,300,270};g.drawPolygon(xC,yC,5);//图片g.drawImage(samImage,250,50,this);}}Java实用教程图5.1简单的图形界面Java实用教程将例5.1注释的程序语句//g.clipRect(50,50,180,180);的注释符号去掉,重新编译执行,可以看见如图5.2所示的结果。图5.2裁剪后的图形界面Java实用教程5.4Color类Color类是用来封装颜色的,在上面的例子中多次用到。使用Color对象较为简单的方法是直接使用Color类提供的预定义的颜色,像红色Color.red、橙色Color.orange等;也可以使用RGB颜色模式进行定义。所谓RGB颜色模式是指使用三种基色:红、绿、蓝,通过三种颜色的调整得出其它各种颜色,这三种基色的值范围为0~255。例如Colorc=newColor(255,200,0);定义橙色。表5.1给出常用颜色的RGB值以及对应的类预定义参数。Java实用教程表5.1常用颜色的RGB值以及对应的类预定义参数颜色名预定义颜色值红色值绿色值蓝色值白色Color.white255255255浅灰色Color.lightGray192192192灰色Color.gray128128128深灰色Color.darkGray646464黑色Color.black000红色Color.red25500粉红色Color.pink255175175橙色Color.orange2552000黄色Color.yellow2552550绿色Color.green02550品红色Color.magenta2550255深蓝色Color.cyan0255255蓝色Color.blue00255Java实用教程Color还有一个构造函数,它构造的Color对象用于是否透明显示颜色。publicColor(intred,intgreen,intblue,intalpha)其中:前三个分量即RGB颜色模式中的参数,第四个alpha分量指透明的程度。当alpha分量为255时,表示完全不透明,正常显示;当alpha分量为0时,表示完全透明,前三个分量不起作用,而介于0~255之间的值可以制造出颜色不同的层次效果。Java实用教程【例5.2】测试Color对象,界面如图5.3所示。源程序代码如下://程序文件名UseColor.javaimportjava.awt.;importjava.applet.;importjava.awt.geom.;publicclassUseColorextendsApplet{publicvoidpaint(Graphicsoldg){Graphics2Dg=(Graphics2D)oldg;Java实用教程g.setColor(Color.blue);g.fill(newEllipse2D.Float(50,50,150,150));g.setColor(newColor(255,0,0,0));g.fill(newEllipse2D.Float(50,50,140,140));g.setColor(newColor(255,0,0,64));g.fill(newEllipse2D.Float(50,50,130,130));g.setColor(newColor(255,0,0,128));g.fill(newEllipse2D.Float(50,50,110,110));g.setColor(newColor(255,0,0,255));g.fill(newEllipse2D.Float(50,50,90,90));g.setColor(newColor(255,200,0));g.fill(newEllipse2D.Float(50,50,70,70));}}Java实用教程图5.3颜色测试界面Java实用教程5.5Graphics2D类Graphics2D类继承于Graphics类,提供几何学、坐标变换、颜色管理以及文本排列等的更高级控制。Graphics2D类是Java平台上渲染二维图形、文字、以及图片的基础类,提供较好的对绘制形状、填充形状、旋转形状、绘制文本、绘制图像以及定义颜色的支持。在AWT编程接口中,用户通过Paint方法接收Graphics对象作为参数,若是使用Graphics2D类,就需要在Paint方法中进行强制转换。Publicvoidpaint(Graphicsold){Graphics2Dnew=(Graphics2D)old;}Java实用教程5.5.1绘制形状Graphics2D提供以下两个方法进行形状的绘制:publicabstractvoiddraw(Shapes)根据Graphics2D的环境设置画出形状s,其中Shape接口包含的类如表5.2所示。publicabstractvoidfill(Shapes)画实心形状s。Java实用教程表5.2Graphics2D绘制的图形类类描述Line2D线Rectangle2D矩形RoundRectangle2D圆角矩形Ellipse2D椭圆GeneralPath几何路径Java实用教程其中GeneralPath是一般的几何路径,它的构造函数为:publicGeneralPath()构造一个空的对象。常用的方法有四个,分别如下:publicvoidlineTo(floatx,floaty)从当前坐标点到(x,y)坐标点画一条直线,将此点添加到路径上。publicvoidmoveTo(floatx,floaty)移动到坐标点(x,y),在路径上添加此点。Java实用教程publicvoidquadTo(floatx1,floaty1,floatx2,floaty2)以坐标点(x1,y1)为控制点,在当前坐标点和坐标点(x2,y2)之间插入二次曲线片断。publicvoidcurveTo(floatx1,floaty1,floatx2,floaty2,floatx3,floaty3)以(x1,y1)和(x2,y2)为控制点,在当前坐标点和(x3,y3)之间插入曲线片断。Java实用教程在Draw方法中提到Graphics2D的环境设置。所谓的环境设置是指设置画图的笔画和填充属性等,设置方法分别如下:publicabstractvoidsetStroke(Strokes)设置笔画的粗细。其中Stroke接口中常用BasicStroke类来实现,一个较简单的构造函数为publicBasicStroke(floatwidth)创建实线笔画宽度为width。publicabstractvoidsetPaint(Paintpaint)Java实用教程设置Graphics2D环境的填充属性。其中,paint的值可以为渐变填充类java.awt.GradientPaint,也可以为图形填充类java.awt.TexturePaint,后者将在5.5.3节绘制图像中讲到。渐变填充类常用构造函数为publicGradientPaint(floatx1,floaty1,Colorcolor1,floatx2,floaty2,Colorcolor2,booleancyclic)构建一个渐变GradientPaint对象,在起始坐标点到目标坐标点之间从颜色color1到color2渐变,cyclic为真,循环渐变。Java实用教程【例5.3】演示了几何形状、笔画变换以及颜色渐变显示。其中直线的笔画宽度为10,其它笔画宽度为5,中间三个图形实现绿色到蓝色的循环渐变,后三个图形实现红色到黄色的循环渐变,如图5.4所示。//程序文件名GUI2D.javaimportjava.awt.;importjava.applet.;importjava.awt.geom.;publicclassGUI2DextendsApplet{Java实用教程publicvoidpaint(Graphicsoldg){Graphics2Dg=(Graphics2D)oldg;//设置笔画宽度BasicStrokestroke=newBasicStroke(10);g.setStroke(stroke);//画线Line2Dline=newLine2D.Float(0,0,20,30);g.draw(line);line=newLine2D.Float(50,50,100,50);g.draw(line);Java实用教程line=newLine2D.Float(50,50,50,100);g.draw(line);stroke=newBasicStroke(5);g.setStroke(stroke);//设置渐变填充GradientPaintgt=newGradientPaint(0,0,Color.green,50,30,Color.blue,true);g.setPaint((Paint)gt);//画矩形Rectangle2Drect=newRectangle2D.Float(80,80,40,40);Java实用教程g.draw(rect);rect=newRectangle2D.Float(100,100,40,40);g.fill(rect);//画椭圆Ellipse2Dellipse=newEllipse2D.Float(120,120,30,40);g.draw(ellipse);gt=newGradientPaint(0,0,Color.red,30,30,Color.yellow,true);g.setPaint((Paint)gt);ellipse=newEllipse2D.Float(140,140,20,20);g.fill(ellipse);Java实用教程//画圆角矩形RoundRectangle2DroundRect=newRoundRectangle2D.Float(160,160,40,40,20,20);g.draw(roundRect);roundRect=newRoundRectangle2D.Float(180,180,40,40,20,20);g.fill(roundRect);//画几何图形GeneralPathpath=newGeneralPath();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绘制文本Graphics2D类提供一个文本布局(TextLayout)对象,用于实现各种字体或段落文本的绘制。其构造函数为:publicTextLayout(Stringstring,Fontfont,FontRenderContextfrc)通过字符串string和字体font构造布局。publicvoiddraw(Graphics2Dg2,floatx,floaty)将这个TextLayout对象画到Graphics2D对象g2上的x,y坐标处。publicRectangle2DgetBounds()返回TextLayout对象的区域。Java实用教程【例5.4】测试绘制文本功能,如图5.5所示。源程序代码如下://程序文件GUIText.javaimportjava.awt.;importjava.applet.;importjava.awt.geom.;importjava.awt.font.;publicclassGUITextextendsApplet{publicvoidpaint(Graphicsoldg){Java实用教程Graphics2Dg=(Graphics2D)oldg;//设置字体Fontf1=newFont("Courier",Font.PLAIN,24);Fontf2=newFont("helvetica",Font.BOLD,24);FontRenderContextfrc=g.getFontRenderContext();Stringstr=newString("这是一个文本布局类的实现");Stringstr2=newString("扩充绘制文本的功能");//构造文本布局对象TextLayoutlayout=newTextLayout(str,f1,frc);Point2Dloc=newPoint2D.Float(20,50);Java实用教程//绘制文本layout.draw(g,(float)loc.getX(),(float)loc.getY());//设置边框Rectangle2Dbounds=layout.getBounds();bounds.setRect(bounds.getX()+loc.getX(),bounds.getY()+loc.getY(),bounds.getWidth(),bounds.getHeight());g.draw(bounds);layout=newTextLayout(str2,f2,frc);g.setColor(Color.red);layout.draw(g,20,80);}}Java实用教程图5.5Graphics2D对象绘制文本Java实用教程5.5.3绘制图像绘制图像用到BufferedImage类,BufferedImage类是指存放图像数据的可访问的缓冲。其构造函数为:publicBufferedImage(intwidth,intheight,intimageType)使用宽度(width)、高度(height)和imageType类型构造BufferedImage对象。publicGraphics2DcreateGraphics()Java实用教程用图片填充椭圆的具体过程如下:(1)创建一个Graphics2D,可以画到BufferedImage中。例如构建一个BufferedImage对象buf。BufferedImagebuf=newBufferedImage(img.getWidth(this),img.getHeight(this),BufferedImage.TYPE_INT_ARGB);创建一个临时Graphics2D对象:GraphicstmpG=buf.createGraphics();将图像画入临时缓冲:tmpG.drawImage(img,10,10,this);Java实用教程(2)用TexturePaint类进行填充:publicTexturePaint(BufferedImagetxtr,Rectangle2Danchor)构造TexturePaint对象,需要一个Rectangle2D对象来存放该对象:Rectangle2Drect=newRectangle2D.Float(0,0,h,w);TexturePaintt=newTexturePaint(buf,rect);(3)然后设置填充模式,并进行填充:g.setPaint(t);g.fill(newEllipse2D.Float(100,50,60,60));Java实用教程【例5.5】完成图像显示,并将区域蓝色透明显示,然后进行图片填充,如图5.6所示。源程序代码如下://程序文件名GUIImage.javaimportjava.awt.;importjava.applet.;importjava.awt.geom.;importjava.awt.font.;importjava.awt.image.;importjava.net.;Java实用教程publicclassGUIImageextendsApplet{publicvoidpaint(Graphicsoldg){Graphics2Dg=(Graphics2D)oldg;try{URLimgURL=newURL(getDocumentBase(),"sample.gif");Imageimg=getImage(imgURL);inth=img.getHeight(this);intw=img.getWidth(this);Java实用教程//构造缓冲图像对象BufferedImagebuf=newBufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);//放入临时图形类GraphicstmpG=buf.createGraphics();tmpG.drawImage(img,10,10,this);g.drawImage(buf,10,20,this);//设置透明颜色对象ColortransBlue=newColor(0,0,255,100);g.setColor(transBlue);GeneralPathpath=newGeneralPath();Java实用教程path.moveTo(60,0);path.lineTo(50,100);path.curveTo(160,230,240,140,200,100);g.fill(path);transBlue=newColor(0,0,255,240);g.fill(newEllipse2D.Float(100,100,50,50));Rectangle2Drect=newRectangle2D.Float(0,0,h,w);//图片填充TexturePaintt=newTexturePaint(buf,rect);Java实用教程g.setPaint(t);g.fill(newEllipse2D.Float(100,50,60,60));}catch(Exceptione){System.out.println("Error:"+e.getMessage());}}}Java实用教程图5.6通过Graphics2D对象绘制图像Java实用教程习题1.使用Graphics类进行图形绘制,要求绘制深蓝色矩形和红色椭圆形,然后分别进行填充。2.使用Graphics2D类绘制粉红色到蓝色的渐变,填充到圆角矩形、多边形,笔画宽度为10。3.绘制文本“欢迎来到Java世界”,其中“欢迎来到”为蓝色显示,而“Java世界”为橙色显示,文本用矩形框起来,底色为黄色。4.画一个三角形区域,然后用图片进行填充。Java实用教程第6章Java用户界面技术6.1用户界面对象6.2布局6.3java.swing包习题Java实用教程6.1用户界面对象用户界面上经常用到的组件对象有Button(按钮)、Checkbox(复选框)、Choice(组合框)、Label(标签)、List(列表)、Scrollbar(滚动条)、TextComponent(TextArea(文本区域)、TextField(文本框))和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.awt.TextComponent+--java.awt.TextArea+--java.awt.TextFieldJava实用教程6.1.1按钮Button类创建一个带标签的按钮对象,当按下一个按钮时,可以引发一些事件,包含一系列的动作或操作。例如单击按钮,使得界面颜色发生变化等。它的构造函数以及主要的方法如下:publicButton()构建一个没有标签的按钮。publicButton(Stringlabel)构建一个显示为label的按钮。publicvoidsetLabel(Stringlabel)设置显示标签为字符串label。publicStringgetLabel()获取按钮的标签,返回为字符串。Java实用教程【例6.1】测试Button类的Applet。用户界面如图6.1所示。源程序代码如下://程序文件名UseButton.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseButtonextendsApplet{Stringstr1=newString();//声明按钮对象Buttonb1;Buttonb2;Java实用教程publicvoidinit(){//构造对象b1=newButton();b2=newButton("按钮对象2");//添加到界面this.add(b1);this.add(b2);}publicvoidstart(){Java实用教程b1.setLabel("按钮对象1");str1=b2.getLabel();repaint();}publicvoidpaint(Graphicsg){g.drawString(str1,20,30);}};Java实用教程启动Applet的HTML页面代码如下: Java实用教程图6.1测试Button类的界面Java实用教程6.1.2复选框和单选按钮复选框是一个图形组件,有两个状态,即“选中”(true)和“未选中”(false)。单击复选框时可以在“选中”、“未选中”之间进行切换。在Java编程语言中,单选按钮没有单独的类,而是作为复选框的特例存在,用户通过把一组复选框放置在同一个复选框组中创建一套单选按钮。它的构造函数和其它方法如下:publicCheckbox()创建一个没有标签的复选框。publicCheckbox(Stringlabel)创建一个标签为lable的复选框。Java实用教程publicCheckbox(Stringlabel,booleanstate)创建一个标签为lable的复选框,并设置初始状态。publicCheckboxGroup()创建一个复选框组,用来放置单选按钮。publicCheckbox(Stringlabel,CheckboxGroupgroup,booleanstate)创建一个标签为lable的复选框,添加到group组中并设置初始状态,作为单选按钮的形式出现。Java实用教程publicStringgetLabel()获得复选框的标签。publicvoidsetLabel(Stringlabel)设置标签。publicbooleangetState()返回复选框所在的状态,是选中还是未选中。publicvoidsetState(booleanstate)设置状态,用来初始化复选框的状态。Java实用教程【例6.2】测试复选框和单选按钮的用法,用户界面如图6.2所示。源程序代码如下://程序文件名UseCheckbox.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseCheckboxextendsApplet{Stringstr1=newString();booleanb1=false;booleanb2=false;Java实用教程Checkboxc1,c2,c3;CheckboxcRadio1,cRadio2;CheckboxGroupc;publicvoidinit(){c1=newCheckbox();c2=newCheckbox("复选框对象2");c3=newCheckbox("复选框对象3",true);//构造单选按钮c=newCheckboxGroup();cRadio1=newCheckbox("单选按钮1",c,false);Java实用教程cRadio2=newCheckbox("单选按钮2",c,true);//添加到界面this.add(c1);this.add(c2);this.add(c3);this.add(cRadio1);this.add(cRadio2);}publicvoidstart(){c1.setLabel("复选框对象1");Java实用教程str1=c2.getLabel();b1=c3.getState();b2=cRadio1.getState();repaint();}publicvoidpaint(Graphicsg){g.drawString("获取第二个对象的标签:"+str1,40,80);g.drawString("复选框3的状态为:"+b1,40,100);g.drawString("单选按钮1的状态为:"+b2,40,120);}};Java实用教程图6.2复选框和单选按钮测试Java实用教程6.1.3组合框组合框代表一系列选择的弹出式菜单,当前选择显示为菜单的标题。它的构造函数和其它常用方法如下:publicChoice()构建一个选择项菜单。publicvoidadd(Stringitem)将item添加到选择菜单中。publicStringgetItem(intindex)返回选择菜单中index位置的项,注意索引是从0开始的,而项数从1开始。Java实用教程publicintgetItemCount()返回选择菜单总的项数。publicStringgetSelectedItem()返回当前选中的项。publicintgetSelectedIndex()返回当前选中项的索引。publicvoidinsert(Stringitem,intindex)在index处插入字符串item。publicvoidremove(intposition)删除position位置的项。Java实用教程publicvoidremove(Stringitem)删除item项。publicvoidremoveAll()删除所有的项。publicvoidselect(intpos)将pos处的项设为选中状态,通常用于初始化。publicvoidselect(Stringstr)将str项设为选中状态,通常用于初始化。Java实用教程【例6.3】测试Choice类,用户界面如图6.3所示。源程序代码如下//程序文件名UseChoice.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseChoiceextendsApplet{Stringstr1=newString();Stringstr2=newString();intcount=0;inti1=0;Java实用教程booleanb1=false;Choicec1;//声明组合框对象publicvoidinit(){//初始化组合框对象,c1=newChoice();c1.add("语文");c1.add("数学");c1.add("物理");c1.add("化学");c1.add("生物");c1.select(3);this.add(c1);}Java实用教程publicvoidstart(){count=c1.getItemCount();str1=c1.getItem(2);str2=c1.getSelectedItem();i1=c1.getSelectedIndex();repaint();}publicvoidpaint(Graphicsg){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方法中调用此方法,程序段如下:publicvoidoperate(){c1.insert("英语",3);c1.remove("生物");}publicvoidstart(){operate();count=c1.getItemCount();...}Java实用教程图6.4修改操作后的用户界面Java实用教程6.1.4标签标签对象就是将文本放入一个容器内的组件,显示一行只读文本。文本可以由程序修改,用户无法直接修改。它的构造函数和其它常用方法如下:publicLabel()构建一个空标签。publicLabel(Stringtext)构建一个text内容的标签,默认为左对齐。publicLabel(Stringtext,intalignment)Java实用教程构建一个内容为text,以alignment方式对齐的标签,其中alignment的取值如表6.1所示。表6.1标签alignment的属性取值alignment可选值对应数值对齐方式Label.LEFT0左对齐Label.RIGHT2右对齐Label.CENTER1中间对齐Java实用教程publicStringgetText()获得标签文本。publicvoidsetText(Stringtext)设置标签文本。publicintgetAlignment()获得标签文本对齐方式,返回为整型值。Java实用教程【例6.4】测试Label类,用户界面如图6.5所示。源程序代码如下://程序文件名UseLabel.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseLabelextendsApplet{Stringstr1=newString();inti1=0;Labell1;//声明对象Labell2;Java实用教程Labell3;publicvoidinit(){l1=newLabel();l2=newLabel("标签对象2");l3=newLabel("标签对象3",Label.CENTER);this.add(l1);this.add(l2);this.add(l3);}publicvoidstart(){Java实用教程l1.setText("标签对象1");str1=l2.getText();i1=l3.getAlignment();repaint();}publicvoidpaint(Graphicsg){g.drawString("获取第二个对象的文本:"+str1,40,60);g.drawString("标签对象3的对齐方式为:"+i1,40,80);}};Java实用教程图6.5Label对象的界面Java实用教程6.1.5列表List展示给用户一个滚动的文本项列表。用户可以选择其中一项或多项。它的构造函数和其它常用方法如下:publicList()构建一个新的空滚动列表。publicList(introws)构建一个新的rows可见行的滚动列表。publicList(introws,booleanmultipleMode)构建一个新的rows可见行的滚动列表,并设置是否可以多项选择。multipleMode为true时,允许用户多项选择。Java实用教程publicvoidadd(Stringitem)在滚动列表最后添加新的一项item。publicvoidadd(Stringitem,intindex)在index位置添加item项。publicStringgetItem(intindex)返回index位置的项。publicintgetItemCount()返回列表中项的数目。publicString[]getItems()返回列表中的项,为一个字符串数组。Java实用教程publicintgetSelectedIndex()返回列表中选中项的索引。publicStringgetSelectedItem()返回列表中选中的项。publicbooleanisIndexSelected(intindex)判断index项是否选中。publicvoidremove(intposition)删除position项。publicvoidremove(Stringitem)删除item项。Java实用教程publicvoidremoveAll()删除列表中所有元素。publicvoidreplaceItem(StringnewValue,intindex)将index位置的项替换为newValue。publicvoidselect(intindex)选中index位置的项,通常用于初始化。Java实用教程【例6.5】测试List类,用户界面如图6.6所示。源程序代码如下://程序文件名UseList.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseListextendsApplet{Stringstr1=newString();Stringstr2=newString();inti1=0;inti2=0;Java实用教程Listl1,l2,l3;//声明对象publicvoidinit(){l1=newList();l2=newList(5);l3=newList(5,true);//列表添加内容l1.add("苹果");l1.add("香蕉");l1.add("梨");l2.add("语文");l2.add("数学");Java实用教程l2.add("英语");l2.add("化学");l3.add("钢笔");l3.add("铅笔");l1.select(1);l3.select(1);this.add(l1);this.add(l2);this.add(l3);}publicvoidstart(){Java实用教程str1=l1.getItem(2);i1=l1.getItemCount();l2.replaceItem("英语",2);str2=l3.getSelectedItem();repaint();}publicvoidpaint(Graphicsg){g.drawString("第一个对象的索引为2的元素:"+str1,40,100)g.drawString("第一个对象的元素个数:"+i1,40,120);g.drawString("第三个对象选中的元素为:"+str2,40,140);}};Java实用教程图6.6List对象的界面Java实用教程6.1.6滚动条Scrollbar给用户提供一个组件,方便用户在一系列范围的值中进行选择。它的常用属性如表6.2所示。表6.2Scrollbar类的常用属性及缺省值属性描述缺省值Orientation(方向)水平还是垂直Scrollbar.VERTICAL(1)Minimum(最小值)滚动条的最小值0Maximum(最大值)滚动条的最大值100Value(数值)滚动条的值0Unitincrement(单位移动)单击滚动条两端箭头时移动的单位1Blockincrement(块移动)单击滚动条空白处时移动的单位10Java实用教程它的构造函数和其它常用方法如下:publicScrollbar()构建一个新的垂直滚动条。publicScrollbar(intorientation)构建一个指定方向的滚动条。Orientation的值为HORIZONTAL(0)表示水平滚动条,值为VERTICAL(1)表示垂直滚动条。publicScrollbar(intorientation,intvalue,intvisible,intminimum,intmaximum)构建一个指定方向、初始值、可见性、最小值和最大值的滚动条。Java实用教程publicintgetValue()返回滚动条的当前值。publicintgetMinimum()返回最小值。publicintgetMaximum()返回最大值。Java实用教程【例6.6】测试Scrollbar类,用户界面如图6.7所示。源程序代码如下//程序文件名UseScrollbar.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseScrollbarextendsApplet{inti1=0;inti2=0;inti3=0;inti4=0;inti5=0;Scrollbars1;//声明对象Java实用教程Scrollbars2;Scrollbars3;publicvoidinit(){s1=newScrollbar();s2=newScrollbar(Scrollbar.HORIZONTAL);s3=newScrollbar(Scrollbar.VERTICAL,50,0,10,500);this.add(s1);this.add(s2);this.add(s3);}publicvoidstart(){Java实用教程i1=s1.getOrientation();i2=s2.getOrientation();i3=s3.getValue();i4=s3.getMinimum();i5=s3.getMaximum();repaint();}publicvoidpaint(Graphicsg){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.7Scrollbar对象的测试界面Java实用教程6.1.7文本框TextField对象用作单行文本的编辑。它的构造函数和其它常用方法如下:publicTextField()构建一个空的文本框。publicTextField(intcolumns)构建一个文本框,columns给出文本框的宽度。publicTextField(Stringtext)构建一个文本框,用text给出初始化内容。publicTextField(Stringtext,intcolumns)Java实用教程构建一个文本框,text给出初始化的内容,columns给出文本框的宽度。publicvoidsetText(Stringt)将文本框的内容设置为特定文本t。publicStringgetText()返回文本框的内容,返回值为字符串。publicvoidsetEditable(booleanb)设定文本框内容是否是用户可编辑的,b为false时,表示不可编辑,b为true时,表示可编辑。通常创建一个文本框时默认为用户可编辑的。publicintgetColumns()获取列数。Java实用教程【例6.7】TextField类的测试,用户界面如图6.8所示。源程序代码如下://程序文件名UseTextField.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseTextFieldextendsApplet{Stringstr1=newString();inti1=0;inti2=0;TextFieldtf1,tf2,tf3,tf4;publicvoidinit(){Java实用教程tf1=newTextField();tf2=newTextField(20);tf3=newTextField("文本对象3");tf4=newTextField("文本对象4",30);add(tf1);add(tf2);add(tf3);add(tf4);}publicvoidstart(){Java实用教程tf1.setText("文本对象1");tf2.setText("文本对象2");str1=tf3.getText();i1=tf3.getColumns();i2=tf4.getColumns();tf4.setEditable(false);repaint();}publicvoidpaint(Graphicsg){g.drawString("第三个对象的文本内容为:"+str1,20,140);g.drawString("第三个对象的列数为:"+i1,20,160);g.drawString("第四个对象的列数为:"+i2,20,180);}};Java实用教程图6.8TextField对象的界面Java实用教程6.1.8文本区域TextArea对象用于允许多行编辑的文本区域,可以设置为可编辑的,也可以设为只读属性。publicTextArea()构建一个空文本区域。publicTextArea(introws,intcolumns)构建一个行数为rows、列数为columns的空文本区域。publicTextArea(Stringtext)构建一个文本为text的文本区域。Java实用教程publicTextArea(Stringtext,introws,intcolumns)构建一个文本为text、行数为rows、列数为columns的文本区域。publicTextArea(Stringtext,introws,intcolumns,intscrollbars)构建一个文本为text、行数为rows、列数为columns的文本区域。滚动条的情况由scrollbars参数决定。Scrollbars的取值如表6.3所示。Java实用教程表6.3TextArea中的滚动条属性值参数描述值SCROLLBARS_BOTH创建和显示水平滚动条和垂直滚动条0SCROLLBARS_VERTICAL_ONLY创建和显示垂直滚动条1SCROLLBARS_HORIZONTAL_ONLY创建和显示水平滚动条2SCROLLBARS_NONE没有任何滚动条3Java实用教程publicvoidappend(Stringstr)将非空str字符串文本添加到文本区域中。publicvoidinsert(Stringstr,intpos)在指定位置pos插入非空字符串str。publicvoidreplaceRange(Stringstr,intstart,intend)将start开始位置到end结束位置的字符串替换成非空字符串str,其中start位置的字符被替换,end位置的字符仍保留。publicvoidsetText(Stringt)将文本框的内容设置为特定文本t。Java实用教程publicStringgetText()返回文本框的内容,返回值为字符串。publicvoidsetEditable(booleanb)设定文本框内容是否是用户可编辑的。b为false时,表示不可编辑。b为true时,表示可编辑。通常创建一个文本框时,默认为用户可编辑的。publicintgetColumns()返回列数。publicintgetRows()返回行数。Java实用教程【例6.8】测试TextArea类,用户界面如图6.9所示。源程序代码如下://程序文件名UseTextArea.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUseTextAreaextendsApplet{Stringstr1=newString();Stringstr2=newString();inti1,i2,i3;TextAreat1,t2,t3,t4,t5;//声明对象Java实用教程publicvoidinit(){t1=newTextArea();t2=newTextArea(2,20);t3=newTextArea("文本区域对象3");t4=newTextArea("文本区域对象4",3,10);t5=newTextArea("文本区域对象5",2,24,TextArea.SCROLLBARS_BOTH);this.add(t1);this.add(t2);this.add(t3);this.add(t4);this.add(t5);}Java实用教程publicvoidstart(){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实用教程}publicvoidpaint(Graphicsg){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.9TextArea对象的界面Java实用教程6.2布局6.2.1流式布局器流式布局将组件按照从左到右的顺序自然排列,是缺省的设置方式。其构造函数如下:FlowLayout()构建一个新的流式布局器,中央对齐,对象之间以5单元水平和垂直间隔。FlowLayout(intalign)构建一个新的流式布局器,通过align设置对齐方式,对象之间以5单元水平和垂直间隔。FlowLayout(intalign,inthgap,intvgap)构建一个新的流式布局器,通过align设置对齐方式,对象之间以hgap单元水平间隔并以vgap单元垂直间隔。Java实用教程6.2.2边缘布局器边缘布局器是一个分为北(NORTH)、南(SOUTH)、东(EAST)、西(WEST)和中央(CENTER)五部分的容器。其构造函数如下:BorderLayout()构建一个新的边缘布局,对象之间没有间隔。BorderLayout(inthgap,intvgap)构建一个新的边缘布局,对象之间的水平间隔为hgap,垂直间隔为vgap。Java实用教程6.2.3面板面板是最简单的容器类,应用程序可以在面板提供的空间里放置任意组件及其它的面板。Panel()使用缺省的布局管理器创建一个新的面板。缺省的布局管理器为流式管理器。Panel(LayoutManagerlayout)用指定的layout布局管理器创建一个面板。publicvoidsetLayout(LayoutManagermgr)设置布局管理器。Java实用教程【例6.9】下面是一个综合性实例,采用本章介绍的界面对象设置用户界面并进行布局管理。经过布局后的界面如图6.10所示。//程序文件名UsePanel.javaimportjava.awt.;importjava.applet.;importjava.applet.Applet;publicclassUsePanelextendsApplet{LabellblName,lblNumber,lblSex,lblJob,lblText;TextFieldtfName,tfNumber;CheckboxchMale,chFemale;Java实用教程CheckboxGroupc;TextAreataText;ChoicechJob;ButtonbtnOk,btnCancel;Panelp1,p2,p3,p4,p5,p6,p7,p8,p9;publicvoidinit(){lblName=newLabel("姓名:");lblNumber=newLabel("身份证号:");lblSex=newLabel("性别");lblJob=newLabel("职业");lblText=newLabel("个性化宣言:");Java实用教程tfName=newTextField(23);tfNumber=newTextField(20);taText=newTextArea(10,20);c=newCheckboxGroup();chMale=newCheckbox("男",c,true);chFemale=newCheckbox("女",c,false);chJob=newChoice();chJob.add("计算机业");chJob.add("医生");chJob.add("教师");chJob.add("军队");btnOk=newButton("确定");btnCancel=newButton("取消");Java实用教程p1=newPanel();p2=newPanel();p3=newPanel();p4=newPanel();p5=newPanel();p6=newPanel();p7=newPanel(newBorderLayout());p8=newPanel();p9=newPanel(newBorderLayout());p1.add(lblName);p1.add(tfName);p2.add(lblNumber);p2.add(tfNumber);p3.add(lblSex);Java实用教程p3.add(chMale);p3.add(chFemale);p4.add(lblJob);p4.add(chJob);p5.add(p3);p5.add(p4);p6.setLayout(newBorderLayout());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(newFlowLayout(FlowLayout.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.3java.swing包6.3.1基本组件JButton为轻量级按钮组件,对应着Button组件类。JLabel为轻量级标签组件,对应着Label组件类。JCheckBox为轻量级复选框,对应CheckBox类。JradioButton为轻量级单选按钮,需要添加在ButtonGroup组中。JRadioButtonjMale=newJRadioButton("男");JRadioButtonjFemale=newJRadioButton("女");Java实用教程ButtonGroupgroup=newButtonGroup();group.add(jMale);group.add(jFemale);JComoBox对应Choice组件,但添加项的方法不同,使用的是addItem方法,例如:JComboBoxcmbJob=newJComboBox();cmbJob.addItem("计算机业");cmbJob.addItem("医生");cmbJob.addItem("教师");Java实用教程cmbJob.addItem("军队");JTextField组件为允许对单行文本进行编辑的轻量级组件,对应TextField类。JTextArea组件用于在多行区域中显示纯文本并进行编辑。Jpanel为轻量级面板控件,对应原来的Panel类。JApplet类继承自Applet类。Java实用教程6.3.2JTableJTable是用于显示和编辑的两维表单元。它的构造函数和常用方法为:publicJTable()构造一个空的JTable对象。publicvoidsetModel(TableModeldataModel)为表对象设置数据模型dataModel,并将新数据模型进行注册。DefaultTableModel是一个实现模型,使用一系列Vector对象实现表单元数据的填充。它的构造函数和常用方法为:publicDefaultTableModel()构造函数。Java实用教程publicvoidaddColumn(ObjectcolumnName)添加一列标题。publicvoidaddRow(VectorrowData)在模型对象的末尾添加一行Vector对象的数据。构造Jtable对象的步骤如下:(1)构造一个空JTable对象。JTabletblInf=newJTable();(2)构造DefaultTableModel对象,用setModel方法将此对象绑定到JTable上。DefaultTableModeldtm=newDefaultTableModel();Java实用教程(3)具体实现DefaultTableModel对象(addColomn方法实现列标题设置,addRow方法实现数据行添加)。①初始化Vector列表,添加列标题。VectorvCdata=newVector();vCdata.add("姓名");vCdata.add("身份证号");vCdata.add("性别");tblInf.setModel(dtm);for(inti=0;i”,单击“编辑规则项目”按钮,弹出如图10.10所示窗口。权限列表中可以看出对普通属性都有读的权限。这是客户端对所有远程代码的默认的安全限制列表。Java实用教程图10.10所有远程代码访问的默认权限列表Java实用教程这个默认的java.policy文件对应的源文件如下://StandardextensionsgetallpermissionsbydefaultgrantcodeBase"file:${java.home}/lib/ext/"{permissionjava.security.AllPermission;};//defaultpermissionsgrantedtoalldomainsJava实用教程grant{//Allowsanythreadtostopitselfusingthejava.lang.Thread.stop()//methodthattakesnoargument.//Notethatthispermissionisgrantedbydefaultonlytoremain//backwardscompatible.//Itisstronglyrecommendedthatyoueitherremovethispermission//fromthispolicyfileorfurtherrestrictittocodesources//thatyouspecify,becauseThread.stop()ispotentiallyunsafe.Java实用教程//See"http://java.sun.com/notes"formoreinformation.permissionjava.lang.RuntimePermission"stopThread";//allowsanyonetolistenonun-privilegedportspermissionjava.net.SocketPermission"localhost:1024-","listen";//"standard"properiesthatcanbereadbyanyonepermissionjava.util.PropertyPermission"java.version","read";permissionjava.util.PropertyPermission"java.vendor","read";permissionjava.util.PropertyPermission"java.vendor.url","read";Java实用教程permissionjava.util.PropertyPermission"java.class.version","read";permissionjava.util.PropertyPermission"os.name","read";permissionjava.util.PropertyPermission"os.version","read";permissionjava.util.PropertyPermission"os.arch","read";permissionjava.util.PropertyPermission"file.separator","read";permissionjava.util.PropertyPermission"path.separator","read";permissionjava.util.PropertyPermission"line.separator","read";Java实用教程permissionjava.util.PropertyPermission"java.specification.version","read";permissionjava.util.PropertyPermission"java.specification.vendor","read";permissionjava.util.PropertyPermission"java.specification.name","read";permissionjava.util.PropertyPermission"java.vm.specification.version","read";permissionjava.util.PropertyPermission"java.vm.specification.vendor","read";permissionjava.util.PropertyPermission"java.vm.specification.name","read";permissionjava.util.PropertyPermission"java.vm.version","read";permissionjava.util.PropertyPermission"java.vm.vendor","read";permissionjava.util.PropertyPermission"java.vm.name","read";};Java实用教程10.5签名及发布的例子10.5.1步骤在命令提示符状态下进入路径D:\ApacheTomcat4.0\webapps\ROOT\user,所有操作都在服务器路径下操作,也可以在普通路径下操作,完成后将一系列文件配置到服务器端。本书作者使用前者,在user目录下建立AppletSecurity.java文件,源代码即为例10.1,编译后生成三个类:AppletSecurity.class、AppletSecurity$1.class和AppletSecurity$2.class。(1)将生成的类文件打包成文档文件。jarcvfa.jar.classJava实用教程(2)为刚才创建的文件创建keystore。keytool-genkey-aliasa-keypassxueliang-keystorea.keystore-storepassxueliang(3)使用刚才生成的钥匙来对jar文件进行签名。jarsigner-keystorea.keystore-storepassxuelianga.jara(4)将公共钥匙导入到一个cer文件中。keytool-export-aliasa-filea.cer-keystorea.keystore-storepassxueliangJava实用教程(5)网页转换及修改。嵌入类的index.html写成: Java实用教程使用htmlConverter工具,将index.html转换成使用插件的文件。源文件如下:Java实用教程 Java实用教程10.5.2结果通过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世界”。编写的界面如图10.14所示,文件名中写入路径,文件内容中写入数据,单击“存储”按钮,将数据存入客户端文件,单击“打开”按钮,又可以显示内容,将可能出现的异常输出到文本区域内。2.使用PolicyTool工具建立一个new.policy文件,要求对网址http://192.100.100.43::79端口下所有访问进行许可授权。3.为习题1的Applet加入数字签名,并进行访问。Java实用教程图10.14用户界面Java实用教程第11章Java网络技术(一)11.1TCPSockets基础11.2UDPSockets基础11.3网页显示控件习题Java实用教程11.1TCPSockets基础Sockets是一个编程抽象概念,它是网络上与另一个应用程序通信连接的句柄。Sockets编程将用户代码与TCP/IP协议堆栈的底层实现隔离开,允许用户灵活地实现自己的编程。基于TCP协议的TCPSockets需要四个方面的数据:(1)本地系统的IP地址。(2)本地应用程序正在使用的TCP端口号。(3)通信的远程系统的IP地址。(4)通信的远程系统响应的TCP端口号。Java实用教程TCPSockets的应用模型通常是客户/服务器模型,一个服务器在一个特定端口等待远程计算机请求资源,给予响应。客户程序绑定到这个端口,建立一个可靠连接来用于通信。面向连接的操作使用TCP协议,在这个模式下的Socket必须在发送数据之前与目的地的Socket取得一个连接。连接建立后,Socket就可以使用一个流接口:打开—读—写—关闭。所有发送的信息都会在另一端以同样的顺序被接收。面向连接的操作比无连接的操作效率低,但是数据的安全性更高。由于Socket使用是双方的,所以在客户端和服务器端的使用稍有不同。Java实用教程(1)客户端请求Socket的步骤如下:①建立客户端Socket连接;②得到Socket的读和写的流;③利用流;④关闭流;⑤关闭Socket。使用一个服务器端的Socket请求比使用一个客户端Socket请求要麻烦一些。服务器并不是主动地建立连接。相反地,服务器被动地监听客户端的连接请示,然后给它们服务。Java实用教程(2)服务器端Socket要完成以下的基本的步骤:①建立一个服务器Socket并开始监听;②使用accept()方法取得新的连接;③建立输入和输出流;④在已有的协议上产生会话;⑤关闭客户端流和Socket;⑥回到②或者转到⑦;⑦关闭服务器Socket。Java实用教程图11.1面向连接的Socket协作流程图ÇëÇó/Ó¦´ð½¨Á¢Á¬½Ó·þÎñÆ÷¿Í»§¶Ë½¨Á¢Socket(·µ»ØSocketºÅS1)°ó¶¨(SocketÓë±¾µØµØÖ·ÏàÁ¬)¼àÌý(֪ͨTCP×¼±¸½ÓÊÕÁ¬½Ó)Á¬½Ó(½¨Á¢ÐµÄSocketºÅS2)Êý¾Ý½»»»¹Ø±ÕSocketS2¹Ø±ÕSocketS1½¨Á¢Socket(·µ»ØSocketºÅS1)Á¬½Ó(ÓëÖ÷»úÏàÁ¬)Êý¾Ý½»»»¹Ø±ÕSocket£¬½áÊø¶Ô»°Java实用教程例如,HTTP请求通过服务器的80端口实现,服务器端类似于Socket监听,端口号为80。如果客户端希望通过应用程序获得网页,只需采用面向连接的Socket,请求80端口,获取网页数据。首先打开一个连接,请求主机为服务器网址,请求端口号为80,然后发送命令请求“GET/HTTP/1.0\r\n\r\n”,得到返回的网页。Java实用教程11.1.1InetAddress类InetAddress对象表示一个Internet主机地址。这个主机地址可以通过名字和IP地址来标识。名字即主机名,例如本机名字为snowing,为字符串类型;IP地址为192.100.100.43,为四字节的数字,书写形式为a.b.c.d。InetAddress类的几个常用方法如下:publicstaticInetAddressgetByName(Stringhost)throwsUnknownHostException通过名字可以得到主机的IP地址。Java实用教程publicStringgetHostAddress()返回IP地址的字符串格式。publicStringgetHostName()返回IP地址的主机名。publicstaticInetAddressgetLocalHost()throwsUnknownHostException以InetAddress类封装的格式返回本机地址。publicStringtoString()转换成字符串格式。Java实用教程【例11.1】InetAddress对象应用的测试。获取本机地址并转换成字符串输出,输出本地主机名和IP地址以及通过局域网内计算机的名字得到它的IP地址。程序源代码如下://程序文件名FindHost.javaimportjava.net.;publicclassFindHost{publicstaticvoidmain(String[]args){try{Java实用教程InetAddressh=InetAddress.getLocalHost();System.out.println("toString():"+h.toString());System.out.println("getHostName():"+h.getHostName());System.out.println("getHostAddress():"+h.getHostAddress());h=InetAddress.getByName("engine");System.out.println(h.getHostName()+":"+h.getHostAddress());}catch(UnknownHostExceptione){System.out.println(e.getMessage());}}}Java实用教程编译后生成FindHost.class文件,运行后输出结果界面如图11.2所示。由图11.2可以看出本地主机名为snowing,IP地址192.100.100.43;engine为局域网内另一台计算机的名字,可以得到它的IP地址为192.100.100.186。Java实用教程图11.2程序结果输出界面Java实用教程11.1.2Socket类Socket类用来实现客户端的Socket。常用的构造方法有以下三种:publicSocket()创建一个无连接的Socket。publicSocket(InetAddressaddress,intport)创建流式Socket,将它连接到InetdAdress类指明的主机和port端口上。publicSocket(Stringhost,intport)创建流式Socket并将它连接到特定host的特定port端口上。Java实用教程【例11.2】建立客户端程序,访问网址http://www.xjtu.edu.cn,返回网址的首页写入文件xjtu.html。1.程序建立的步骤(1)建立到http://www.xjtu.edu.cn且端口为80的Socket连接。SocketclientSocket=newSocket("www.xjtu.edu.cn",80);Java实用教程(2)初始化字节流。连接建立后的数据传输通过数据输入输出流实现,写文件又通过文件输入输出流来实现。各种流对象的初始化如下:DataOutputStreamoutbound=newDataOutputStream(clientSocket.getOutputStream());DataInputStreaminbound=newDataInputStream(clientSocket.getInputStream());InputStreamReaderinS=newInputStreamReader(inbound);Filef=newFile("xjtu.html");FileOutputStreamfOut=newFileOutputStream(f);PrintStreamp=newPrintStream(fOut);Java实用教程(3)发送请求。outbound.writeBytes("GET/HTTP/1.0\r\n\r\n");(4)返回数据后,循环写入文件。intc;while((c=inS.read())!=-1)p.print((char)c);Java实用教程(5)关闭流。inS.close();outbound.close();inbound.close();clientSocket.close();Java实用教程2.程序源文件//程序文件名ReadClient.javaimportjava.io.;importjava.net.;publicclassReadClient{publicstaticvoidmain(Stringargs[]){try{Java实用教程//初始化Socket对象SocketclientSocket=newSocket("www.xjtu.edu.cn",80);System.out.println("Client1:"+clientSocket);//初始化流对象DataOutputStreamoutbound=newDataOutputStream(clientSocket.getOutputStream());DataInputStreaminbound=newDataInputStream(clientSocket.getInputStream());InputStreamReaderinS=newInputStreamReader(inbound);Filef=newFile("xjtu.html");Java实用教程FileOutputStreamfOut=newFileOutputStream(f);PrintStreamp=newPrintStream(fOut);outbound.writeBytes("GET/HTTP/1.0\r\n\r\n");//写入文件intc;while((c=inS.read())!=-1)p.print((char)c);//关闭流inS.close();outbound.close();inbound.close();clientSocket.close();Java实用教程}catch(UnknownHostExceptionuhe){System.out.println("UnknownHostException:"+uhe);}catch(IOExceptionioe){System.err.println("IOException:"+ioe);}}}Java实用教程3.输出结果图11.3为程序输出的xjtu.html,而图11.4为网址http://www.xjtu.edu.cn的首页,可以看出程序输出的网页图形丢失,这是因为此处的数据输入输出流只实现文本的读取,而并未考虑图形的处理。Java实用教程图11.3程序输出的xjtu.htmlJava实用教程图11.4网址http://www.xjtu.edu.cn的首页Java实用教程11.1.3ServerSocket类ServerSocket类实现服务器Socket,服务器Socket等待从网络到达的请求,基于这些请求完成操作,然后返回相应的结果给请求者。ServerSocket类有一个重要的方法:publicSocketaccept()用户监听并接收一个连接。【例11.3】编写TCP通信程序,服务器端发送字符串到客户端。Java实用教程1.服务器端程序建立的步骤(1)创建服务器Socket(端口82,限制5个连接)和接收客户连接的Socket。serverSocket=newServerSocket(82,5);SocketclientSocket=newSocket();(2)等待客户端连接。clientSocket=serverSocket.accept();Java实用教程(3)初始化输入输出流。DataInputStreaminbound=newDataInputStream(client.getInputStream());DataOutputStreamoutbound=newDataOutputStream(client.getOutputStream());Java实用教程(4)当接收到“hello”字符串时,输出字符串“http://www.xjtu.edu.cntringBufferbuffer=newStringBuffer("\"http://www.xjtu.edu.cn/\"\r\n");tringinputLine;while((inputLine=inbound.readLine())!=null)if(inputLine.equals("hello")){outbound.writeBytes(buffer.toString());break;}Java实用教程(5)关闭流以及Socket。outbound.close();inbound.close();clientSocket.close();Java实用教程2.服务器端程序源文件//程序文件名SimpleWebServer.javaimportjava.io.;importjava.net.;publicclassSimpleWebServer{publicstaticvoidmain(Stringargs[]){ServerSocketserverSocket=null;SocketclientSocket=null;intconnects=0;try{Java实用教程//创建服务器Socket,端口82,限制5个连接serverSocket=newServerSocket(82,5);while(connects<5){//等待连接clientSocket=serverSocket.accept();//操作连接ServiceClient(clientSocket);connects++;}serverSocket.close();}Java实用教程catch(IOExceptionioe){System.out.println("ErrorinSimpleWebServer:"+ioe);}}publicstaticvoidServiceClient(Socketclient)throwsIOException{DataInputStreaminbound=null;DataOutputStreamoutbound=null;try{//获取输入输出流inbound=newDataInputStream(client.getInputStream());Java实用教程outbound=newDataOutputStream(client.getOutputStream());StringBufferbuffer=newStringBuffer("\"http://www.xjtu.edu.cn/\"\r\n");StringinputLine;while((inputLine=inbound.readLine())!=null){//判断输入为hello时输出字符串if(inputLine.equals("hello")){outbound.writeBytes(buffer.toString());break;Java实用教程}}}finally{//打印清除连接,关闭流及SocketSystem.out.println("Cleaningupconnection:"+client);outbound.close();inbound.close();client.close();}}}Java实用教程3.客户端程序//程序文件名为ReadClient.javaimportjava.io.;importjava.net.;publicclassReadClient{publicstaticvoidmain(Stringargs[]){try{//与服务器建立连接Java实用教程SocketclientSocket=newSocket("192.100.100.43",82);System.out.println("Client1:"+clientSocket);//初始化流对象DataOutputStreamoutbound=newDataOutputStream(clientSocket.getOutputStream());DataInputStreaminbound=newDataInputStream(clientSocket.getInputStream());InputStreamReaderinS=newInputStreamReader(inbound);//发送数据outbound.writeBytes("hello\r\n");Java实用教程System.out.println("hello");outbound.flush();intc;while((c=inS.read())!=-1){System.out.print((char)c);}}catch(UnknownHostExceptionuhe){System.out.println("UnknownHostException:"+uhe);}Java实用教程catch(IOExceptionioe){System.err.println("IOException:"+ioe);}finally{//关闭流及clientSocketinS.close();outbound.close();inbound.close();clientSocket.close();}}}Java实用教程4.通信结果输出通信结果如图11.5所示。上面的部分为服务器端的输出,清除每次连接的Socket,下面的部分为客户端显示,首先打印客户端Socket情况,然后打印发送的hello数据,最后输出从服务器端返回的字符串。Java实用教程图11.5基于TCP的Socket通信结果输出界面Java实用教程11.2UDPSockets基础数据报Socket是包发送服务的接收和发送点,它接收和发送的每个包都是单独访问和路由的。从一个机器发送到另一个机器的包可能有不同的路由,而且可能以任意顺序到达。数据报Socket构造函数有三个,分别如下:publicDatagramSocket()构建数据报Socket,绑定到本地主机上的任意端口。publicDatagramSocket(intport)构建一个数据报Socket,将它绑定到指定的port端口。Java实用教程publicDatagramSocket(intport,InetAddressladdr)构建一个数据报Socket,绑定到指定的laddr本地地址和port端口。数据报可以通过connect方法建立连接,也可以直接使用send方法发送数据,使用receive方法接收数据,方法如下:publicvoidconnect(InetAddressaddress,intport)将建立的数据报Socket连接到远程地址address的port端口。publicvoidreceive(DatagramPacketp)接收数据报包p。publicvoidsend(DatagramPacketp)发送数据报包p。Java实用教程11.2.1DatagramPacket类从TCP的例子程序可以看出TCPSocket发送的数据是流式数据,而UDPSocket发送的数据是分块的数据包,这就用到DatagramPacket类。数据报Socket传输数据前首先构造数据报包,然后传输这个数据报包。数据报包的构造函数如下:DatagramPacket(byte[]buf,intlength)构建数据报包,接收length长度的包并放入buf。DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)构建数据报包,发送length长度的包到address指定的主机的port端口。Java实用教程【例11.4】客户端循环发送数据“Client:Hello”到服务器端,服务器端截取字符串Hello输出,并将源字符串返回给客户端。1.程序建立的步骤(1)服务器端程序建立的步骤。●建立数据报Socket。DatagramSocketmysock=newDatagramSocket(1719);●建立数据报包,准备接收。byte[]buf=newbyte[1024];DatagramPacketp=newDatagramPacket(buf,buf.length);●接收或者发送。mysock.receive(p);...Java实用教程(2)客户端程序建立的步骤。●建立数据报Socket。DatagramSocketmysock=newDatagramSocket();●建立数据报包,准备接收。DatagramPacketp=newDatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1719);●接收或者发送。mysock.receive(p);...mysock.send(p);Java实用教程2.服务器端源程序//程序文件名为DatagramServer.javaimportjava.net.;publicclassDatagramServerextendsObject{publicstaticStringReadRAS(Stringstr){intindexstart=str.indexOf(':');intindexend=str.indexOf("o");StringMsg="Server:"+Java实用教程str.substring(indexstart+1,indexend+1);returnMsg;}publicstaticvoidmain(String[]args){try{DatagramSocketmysock=newDatagramSocket(1719);byte[]buf=newbyte[1024];DatagramPacketp=newDatagramPacket(buf,buf.length);while(true){Java实用教程mysock.receive(p);System.out.println("RECEIVE:"+newString(p.getData()).trim());System.out.println(ReadRAS(newString(p.getData()).toString()));mysock.send(p);System.out.println("SEND:"+newString(p.getData()).trim());}}catch(Exceptione){System.out.println(e.getMessage());}}}Java实用教程3.客户端源程序//程序文件名为DatagramClient.javaimportjava.net.;importjava.io.;publicclassDatagramClientextendsObject{publicstaticvoidmain(String[]args){try{Java实用教程DatagramSocketmysock=newDatagramSocket();byte[]buf=newbyte[1024];StringsendData=newString("Client:Hello");buf=sendData.getBytes();DatagramPacketp=newDatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1719);while(true){mysock.send(p);System.out.println("SEND:"+newString(p.getData()).trim());Java实用教程mysock.receive(p);System.out.println("GET:"+newString(p.getData()).trim());}}catch(Exceptione){System.out.println(e.getMessage());}}}Java实用教程4.通信结果显示如图11.6所示,上面的一部分为客户端,SEND标志发送数据“Client:Hello”,下面部分为服务器端,可以看见RECEIVE标志的接收到的字符串为客户端发送的数据,然后服务器端将接收到的数据进行截取,显示Hello字符串,前面加了Server标志,最后将原数据返回,在客户端又显示GET标志的接收到的字符串。Java实用教程图11.6数据报Socket通信结果输出界面Java实用教程11.2.2音频采集、播放实例【例11.5】下面给出一个音频采集与播放实例,使用UDPSocket和多线程技术实现局域网内部的声音采集与传输。实例采用对等访问模式,使用时只需输入JavaUDPTalk“对方服务器IP地址”,然后单击“通话”按钮即可,如图11.7所示。本例是Applet和应用程序共用的,如果通过Applet进行访问,需要获取SERVER_NAME参数,或者在程序内写成定值。另外,还需为此Applet进行数字签名,否则无权在客户端的机器上进行音频采集。Java实用教程//程序文件名为TalkSelf.javaimportjava.io.;importjava.applet.;importjava.applet.Applet;importjava.awt.;importjava.awt.event.;importjavax.sound.sampled.;importjava.net.;publicclassTalkSelfextendsAppletimplementsRunnable,ActionListener{Java实用教程privatestaticStringSERVER_NAME;//="192.100.100.42";privatestaticintSRTPPort=1734;privatestaticintMAXBUFFER=8192;finalintbufSize=16384;privatestaticbooleanPlayButton=false;//是否播放按钮privatestaticbooleankeepRunning=true;//控制循环privatebooleanbRun=false;//控制播放privateThreadTalkThread;privatestaticPlaybackAudioPlayAudio;//播放音频实例privatestaticCaptureAudioCapAudio;//采集音频实例ButtonPlayBtn;//通话按钮ButtonCaptureBtn;//停止按钮Java实用教程//初始化界面publicvoidinit(){PlayBtn=newButton("通话");PlayBtn.addActionListener(this);add(PlayBtn);CaptureBtn=newButton("停止");CaptureBtn.addActionListener(this);add(CaptureBtn);}Java实用教程//启动线程publicvoidstart(){if(TalkThread==null){TalkThread=newThread(this);TalkThread.start();}}//响应动作事件publicvoidactionPerformed(ActionEventevt){StringbtnCaption=evt.getActionCommand();if(btnCaption.equals("通话")){Java实用教程PlayButton=true;}if(btnCaption.equals("停止")){PlayButton=false;bRun=false;}}//实现run函数publicvoidrun(){while(keepRunning){if(PlayButton&&!bRun)Java实用教程{try{bRun=true;CapAudio=newCaptureAudio(SERVER_NAME,SRTPPort);CapAudio.start();PlayAudio=newPlaybackAudio(SRTPPort);PlayAudio.start();}catch(Exceptione){Java实用教程System.out.println(e.getMessage());}}}}//音频播放类classPlaybackAudioextendsThreadimplementsRunnable{SourceDataLineline;Threadthread;DatagramSockets;//数据报SocketDatagramPacketp;//数据报包intRTPPort;//构造函数:取得接收端口Java实用教程PlaybackAudio(intRTPPort){this.RTPPort=RTPPort;}publicvoidstart(){thread=newThread(this);thread.setName("PlaybackAudio");thread.start();}publicvoidrun(){AudioFormatformat=newJava实用教程AudioFormat(8000,16,2,true,true);//设置音频格式DataLine.Infoinfo=newDataLine.Info(SourceDataLine.class,format);//设置数据线try{line=(SourceDataLine)AudioSystem.getLine(info);//获得源数据线信息line.open(format,bufSize);//打开源数据线}catch(LineUnavailableExceptionex){return;}Java实用教程byte[]data=newbyte[MAXBUFFER];intnumBytesRead=0;line.start();//启动源数据线try{s=newDatagramSocket(RTPPort);}catch(IOExceptione){return;}while(thread!=null){Java实用教程try{p=newDatagramPacket(data,data.length);s.receive(p);//接收包numBytesRead=p.getLength();line.write(p.getData(),0,numBytesRead);//写入源数据线}catch(IOExceptione){break;}}Java实用教程s.close();//关闭数据报Socketif(thread!=null){line.drain();}line.stop();line.close();line=null;}}//音频采集类classCaptureAudioextendsThreadimplementsRunnable{Java实用教程TargetDataLineline;Threadthread;DatagramSockets;DatagramPacketp;StringSERVER_NAME;intRTPPort;//构造函数:取得远程服务器名和端口,用于发送数据CaptureAudio(StringSERVER_NAME,intRTPPort){this.SERVER_NAME=SERVER_NAME;this.RTPPort=RTPPort;}publicvoidstart(){Java实用教程thread=newThread(this);thread.setName("CaptureAudio");thread.start();}publicvoidrun(){AudioFormatformat=newAudioFormat(8000,16,2,true,true);//AudioFormat(floatsampleRate,intsampleSizeInBits,intchannels,booleansigned,booleanbigEndian)DataLine.Infoinfo=newDataLine.Info(TargetDataLine.class,format);Java实用教程try{line=(TargetDataLine)AudioSystem.getLine(info);//设置目标数据线信息line.open(format,line.getBufferSize());//打开目标数据线}catch(Exceptionex){return;}byte[]data=newbyte[MAXBUFFER];intnumBytesRead=0;line.start();//启动目标数据线tryJava实用教程{//构造数据报Sockets=newDatagramSocket();}catch(Exceptionex){return;}while(thread!=null){try{numBytesRead=line.read(data,0,MAXBUFFER);//读取采集数据Java实用教程p=newDatagramPacket(data,numBytesRead,InetAddress.getByName(SERVER_NAME),RTPPort);s.send(p);//发送数据}catch(Exceptionex){break;}}s.close();line.stop();line.close();line=null;}}Java实用教程//主函数publicstaticvoidmain(Stringargs[]){SERVER_NAME=newString(args[0]);TalkSelft=newTalkSelf();Framef=newFrame();f.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEventevt){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.1JEditorPaneJEditorPane类是一个文本组件,通过实现相应的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常用到的方法如下:publicJEditorPane()构建一个空JeditorPane。publicJEditorPane(Stringurl)构建一个基于URL声明的字符串的JEditorPane。publicJEditorPane(URLinitialPage)构建一个基于特定URL对象的JeditorPane。publicvoidaddHyperlinkListener(HyperlinkListenerlistener)添加一个超链接监听者,通知任何变化,例如选中一Java实用教程publicvoidsetPage(Stringurl)设置显示的URL页面。字符串url表示页面的URL地址。publicvoidsetPage(URLpage)设置显示的URL对象代表的page页面。publicvoidsetText(Stringt)设置指定t内容。publicvoidsetEditable(booleanb)b为true时,可编辑;b为false时,不可编辑,但只有当b为false时,才可以响应超链接事件。Java实用教程11.3.2HyperlinkListener和HyperlinkEventHyperlinkListener是超链接事件监听者接口,继承于EventListener接口,只有一个事件:超链接更新,当点击链接或者进入链接时引发。这个事件的方法为:publicvoidhyperlinkUpdate(HyperlinkEvente)当更新一个超链接时调用此方法。HyperlinkEvent是超链接事件,用于通知有关超文本链接的变化,它有两个常用方法,一个方法用来获得事件的类型,另一个方法是获得超链接指向的URL网址。publicHyperlinkEvent.EventTypegetEventType()Java实用教程表11.1超链接事件的三种类型HyperlinkEvent.EventType描述HyperlinkEvent.ACTIVATED激活超链接HyperlinkEvent.ENTERED进入超链接的文本HyperlinkEvent.EXITED退出超链接的文本publicURLgetURL()返回超链接指向的URL地址。Java实用教程【例11.6】使用JEditorPane显示网页,当单击其中的链接时能够给予响应。1.分析(1)创建JEditorPane对象。JEditorPanejep=newJEditorPane();(2)设置可编辑属性为false。jep.setEditable(false);(3)添加超链接事件监听器。jep.addHyperlinkListener(newLinkFollower(jep));Java实用教程(4)显示网页。jep.setPage(str);(5)链接更新事件的处理。publicvoidhyperlinkUpdate(HyperlinkEventevt){if(evt.getEventType()==HyperlinkEvent.EventType.ACTIVATED)jep.setPage(evt.getURL());}Java实用教程2.源程序//程序文件名为DisplayHtml.javaimportjava.io.;importjava.net.;importjavax.swing.;importjavax.swing.event.;publicclassDisplayHtml{//在新窗口显示网页publicstaticvoidshowNetPage(Stringstr){Java实用教程JEditorPanejep=newJEditorPane();jep.setEditable(false);jep.addHyperlinkListener(newLinkFollower(jep));try{jep.setPage(str);}catch(IOExceptione){jep.setContentType("text/html");jep.setText("Couldnotload"+str+"");}Java实用教程JScrollPanejscrollp=newJScrollPane(jep);JFramef=newJFrame("西安交通大学主页");f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);f.setContentPane(jscrollp);f.setSize(600,400);f.show();}publicstaticvoidmain(String[]args){StringgetURL="http://www.xjtu.edu.cn";showNetPage(getURL);}}Java实用教程//类:新开的网页窗口响应链接点击事件classLinkFollowerimplementsHyperlinkListener{privateJEditorPanejep;publicLinkFollower(JEditorPanejep){this.jep=jep;}//超链接更新事件的处理publicvoidhyperlinkUpdate(HyperlinkEventevt){//判断是否是激活事件if(evt.getEventType()==HyperlinkEvent.EventType.ACTIVATED){Java实用教程try{//显示新的网址jep.setPage(evt.getURL());}catch(Exceptione){System.out.println(e.getMessage());}}}}Java实用教程3.结果分析图11.8JEditorPane显示的网页Java实用教程图11.9响应链接后进入的网页Java实用教程习题1.建立TCPSocket读取http://www.263.net网址的首页,将之存入文件h2.html并在IE中显示此文件。2.建立TCPSocket进行通信,服务器端向客户端传送日期数据。3.使用UDPSocket进行通信,服务器和客户相互传送日期数据。4.仔细学习本章音频操作的实例,修改其中的一些数据,如缓冲值或音频流初始化参数,看是否会影响到音频的质量。5.使用java.swing包中的高级控件显示http://www.263.net网址的首页。Java实用教程第12章Java网络技术(二)12.1URL类12.2URLEncoder类12.3URLDecoder类12.4URLConnection类12.5HttpURLConnection类12.6新IO包的Socket应用习题Java实用教程12.1URL类URL类代表统一资源定位符(UniformResourceLocator),指向WWW上的资源,资源可以是一个文件或者一个目录,也可以是一个更加复杂的对象,如对数据库的查询或者搜索引擎的查询。通常,一个URL可以被拆分成几个部分,例如:http://192.100.100.43:8080/web/index.html?search="Java"其中:(1)http用来描述使用的协议为超文本链接协议。Java实用教程(2)192.100.100.43是信息存放的主机IP地址(也可以是主机名,如www.sohu.com.cn)。(3)端口号为8080,默认都为80端口。(4)web/index.html为HTTP服务器上文件的虚拟路径。(5)?search="Java"为网页上表单使用GET方法进行查询的附加部分,?表示后面跟的是提交的表单的名-值对,格式为“名=值”。search为查询词的名字,Java为查询词的值,即用户要查询的值,提交搜索引擎时可以有0个到多个这样的查询名-值对。Java实用教程URL类用来定位WWW上的资源,从而进行处理,如读取网页等。它的构造函数以及一系列常用的方法如下:publicURL(Stringspec)从指定的字符串spec创建一个URL对象。publicURL(Stringprotocol,Stringhost,intport,Stringfile)从指定的protocol协议、host主机、port端口号和file文件名创建一个URL对象。publicURL(Stringprotocol,Stringhost,Stringfile)从指定的protocol协议、主机名host和文件名file创建一个URL对象。Java实用教程publicObjectgetContent()得到URL的内容。publicStringgetContentType()返回网页内容类型,普通网页为“text/html”。publicStringgetFile()得到URL文件名。publicStringgetHost()得到URL的主机名。publicStringgetPath()得到URL的路径部分。publicintgetPort()得到URL的端口号。Java实用教程publicStringgetProtocol()得到URL的协议名。publicStringgetQuery()得到URL的查询部分。publicURLConnectionopenConnection()返回一个URLConnection对象,代表到URL远程对象的连接。publicInputStreamopenStream()打开到URL的连接,返回读取连接的输入流。publicStringtoExternalForm()构建代表URL对象的字符串。publicStringtoString()转换成字符串,覆盖来自对象的toString()方法。Java实用教程12.2URLEncoder类URLEncoder类是一个工具类,用于HTML表单的编码。类只包含一个静态方法,这个方法将字符串转换成application/x-www-form-urlencodedMIME格式。该方法如下:publicstaticStringencode(Strings,Stringenc)throwsUnsupportedEncodingException使用指定的enc编码格式将字符串s转换为application/x-www-form-urlencoded格式,得以在网上传输。Java实用教程其中:(1)s为要转换的字符串。(2)enc是字符编码格式名称,包括US-ASCII、ISO-8859-1、UTF-8等。Java实用教程【例12.1】将查询表单提交的网址和相应的两个查询“名-值对”使用“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类的引用。QueryStringq=newQueryString("cdtype","GB");q.add("word","Java");Java实用教程2.源程序//程序文件名UseEncode.javaimportjava.net.;importjava.io.;publicclassUseEncode{publicstaticvoidmain(String[]args){StringfullURL="http://bingle.pku.edu.cn/scripts/ftp_search.exe?";//新建QueryString对象,调用方法Java实用教程QueryStringq=newQueryString("cdtype","GB");q.add("word","Java");fullURL+=q.toString();//打印编码后的字符串System.out.println("编码后的字符串:"+fullURL);}}//类:处理请求串,编码成网页识别格式classQueryString{Java实用教程privateStringquery;//构造函数,初始名值对的编码publicQueryString(Objectname,Objectvalue){try{query=URLEncoder.encode(name.toString(),"UTF-8")+"="+URLEncoder.encode(value.toString(),"UTF-8");}catch(UnsupportedEncodingExceptione){System.err.println(e);}}Java实用教程//构造函数publicQueryString(){query="";}//添加名值对,之间用符号&进行连接publicsynchronizedvoidadd(Objectname,Objectvalue){if(!query.trim().equals(""))query+="&";try{query+=URLEncoder.encode(name.toString(),"UTF-8")+"="+URLEncoder.encode(value.toString(),"UTF-8");Java实用教程}catch(UnsupportedEncodingExceptione){System.err.println(e);}}//返回编码后的字符串publicStringtoString(){returnquery;}//清空publicvoidclear(){query="";}}Java实用教程3.结果输出图12.1为搜索引擎提交的查询字符串编码的结果。可以看见提交网址的?后跟了两个名值对,cdtype=GB和word=Java,它们之间用符号&隔开。图12.1编码后字符串输出结果Java实用教程12.3URLDecoder类URLDecoder类是URLEncoder类的解码类。它的构造函数和解码方法如下:publicURLEncoder()publicstaticStringdecode(Strings,Stringenc)使用编码格式enc对application/x-www-form-urlencoded字符串s进行解码。Java实用教程12.4URLConnection类抽象类URLConnection代表应用程序和URL之间通信连接的类的超类。类的实例可以用来读取和写入URL代表的资源。URLConnection类实现的两个方法如表12.1所示。表12.1URLConnection类实现的两个方法方法描述openConnection()处理影响到远程资源的连接参数connect()同资源进行交互,查询头文件和内容Java实用教程上述两个方法的实现步骤如下:(1)调用openConnection方法建立连接对象。(2)操作建立参数和普通请求参数。(3)调用connect方法建立到远程对象的实际连接。(4)远程对象可用,头文件和远程对象的内容可以访问。Java实用教程【例12.2】编写程序,访问天网主页(http://e.pku.edu.cn)并查询Java一词,将查询结果存入result.html文件。1.分析(1)建立URL对象。u=newURL(fullURL);(2)打开到URL对象的连接。conn=u.openConnection();(3)获取输入流。theData=conn.getInputStream();(4)输出到文件。p.println(line);Java实用教程2.源程序//程序文件名Search.javaimportjava.net.;importjava.io.;publicclassSearch{publicstaticvoidmain(Stringargs[]){StringfullURL="http://bingle.pku.edu.cn/scripts/ftp_search.exe?";URLConnectionconn=null;Java实用教程OutputStreamtheControl=null;InputStreamtheData=null;URLu=null;//建立URL对象,参数为请求地址+编码后的请求串try{fullURL+=URLEncoder.encode("cdtype","UTF-8")+"="+URLEncoder.encode("GB","UTF-8");fullURL+="&"+URLEncoder.encode("word","UTF-8")+"="+URLEncoder.encode("Java","UTF-8");u=newURL(fullURL);}Java实用教程catch(UnsupportedEncodingExceptione){System.err.println(e);}catch(MalformedURLExceptione){System.err.println("网页错误:"+fullURL+""+e);System.exit(1);}//打开连接,读入网页流数据try{conn=u.openConnection();theData=conn.getInputStream();//得到网页类型:text/htmlJava实用教程StringcontentType=conn.getContentType();//建立文件对象和读取的流对象Filef=newFile("result.html");FileOutputStreamfOut=newFileOutputStream(f);PrintWriterp=newPrintWriter(fOut);if(contentType.toLowerCase().startsWith("text")){BufferedReaderin=newBufferedReader(newInputStreamReader(theData));Stringline;while((line=in.readLine())!=null){Java实用教程//输出到文件p.println(line);}}else{System.out.println("程序只处理文本响应");System.out.println("得到的类型为:"+contentType);}}catch(IOExceptione){System.err.println(e);System.exit(2);}}}Java实用教程3.结果分析程序运行结果如图12.2所示,左部分为浏览器中天网检索的结果,右部分为程序检索结果result.html,由于没有考虑图片的读取,可以看出程序输出缺少所有的图片,但是文本字符和检索结果都是一致的。Java实用教程图12.2程序检索结果和天网检索结果的对比Java实用教程12.5HttpURLConnection类HttpURLConnection类继承URLConnection类,专门支持HTTP协议相关的特征。每个HttpURLConnection实例完成一个单一的请求,其构造函数如下:protectedHttpURLConnection(URLu)构建一个到URL对象u代表的网络资源的HttpURLConnection连接。publicintgetResponseCode()throwsIOExceptionJava实用教程返回HTTP状态码,如:HTTP/1.0200OKHTTP/1.0401UnauthorizedHttpURLConnection类中有一系列的常量值对应着这些状态码。例如HTTP_OK对应着上面列出的第一个状态码,而HTTP_UNAUTHORIZED对应着第二个状态码。Java实用教程【例12.3】返回www.sohu.com.cn网址的首页,并与从浏览器获得的网页进行比较。//程序文件名为UseHttp.javaimportjava.io.;importjava.net.;publicclassUseHttp{publicstaticvoidmain(String[]args){Stringurlstring="http://www.sohu.com.cn";Stringhttpresp=newString();Stringstatus=newString("good");try{Java实用教程//构造URL对象URLcurrenturl=newURL(urlstring);urlstring=currenturl.toString();//判断是否是HTTP协议if(!currenturl.getProtocol().equals("http")){status=currenturl.getProtocol()+"protocol";}else{//打开连接URLConnectionconn=currenturl.openConnection();//建立HttpURLConnection对象Java实用教程HttpURLConnectionhttpconn=(HttpURLConnection)conn;//判断是否正确返回if(httpconn.getResponseCode()==HttpURLConnection.HTTP_OK){if(httpconn.getContentType().equals("text/html")){//构造文件读写流对象,写入文件InputStreamReaderisr=newInputStreamReader(conn.getInputStream());Filef=newFile("sohu.html");FileOutputStreamfOut=newFileOutputStream(f);PrintWriterp=newPrintWriter(fOut);Java实用教程intc;while((c=isr.read())!=-1){p.write(c);}isr.close();httpconn.disconnect();}elsestatus="Nottext/html";}elsestatus="bad";}}Java实用教程catch(Exceptione){status=e.toString();System.out.println("Exception:"+e.getMessage());}if(status.equals("good")){System.out.println(urlstring);}else{System.out.println(status);System.out.println("BadURL="+urlstring);}}}Java实用教程由图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连接,用线程实现时会遇到一些问题,如操作系统限制、死锁、线程安全违反等。而新I/O提供的特性可以很好地解决这些问题。引入的四个基本抽象类如下:Buffer:包含读写的数据线性流。Charset:将Unicode字符与字节流之间进行相互转换。Channels:可以是Socket、文件或管道,代表双边通信的管道。Selectors:多元异步I/O操作,应用于单个线程或多个线程。Java实用教程12.6.1BuffersBuffer是一个线性、有序的数据集,提供了一种在内存容器中保存一系列原始数据的机制。Buffer进行特定的封装之后只允许读写一种数据类型,例如char、int或double等。共有七种读写不同数据类型的Buffer,如表12.2所示。表12.2读写不同数据类型的BufferBuffer名字存放数据类型Buffer抽象基类ByteBuffer字节CharBuffer字符DoubleBuffer双精度数FloatBuffer单精度数IntBuffer整数LongBuffer长整数ShortBuffer短整数Java实用教程Buffer中涉及到的四个基本概念是capacity(容量)、position(位置)、limit(限制)和mark(标记)。●capacity——Buffer的大小(>=size);●position——在Buffer中目前读写的位置(<=limit);●limit——第一个不应该被读取元素的位置的index(索引号)(<=capacity);●mark——用mark方法设置的可设位置,mark方法可以使用reset来重置position(<=position,>=0)。Java实用教程【例12.4】下面给出一段缓冲操作的代码,依次演示capacity、position和limit的值,代码段为:ByteBufferbuf=ByteBuffer.allocateDirect(8);buf.put((byte)0xca);buf.putShort((short)0xfeba);buf.put((byte)0xbe);buf.flip();Java实用教程代码段分析如下:ByteBufferbuf=ByteBuffer.allocateDirect(8);分配8字节的字节缓冲,position=0、capacity=8、limit=8,如图12.4(a)所示。buf.put((byte)0xca);buf.putShort((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缓冲的变化过程显示0xca0xfe0xba0xbelimit£½4position£½0capacity£½8(c)0xca0xfe0xba0xbecapacity£½8(b)position£½4capacity£½8limit£½8(a)position£½0(c)Java实用教程12.6.2CharsetCharset(字符集)定义了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。以下代码段是对字符buffer进行编码的情况。Java实用教程Charsetcharset=Charset.forName("UTF-8");//ISO-8859-1US-ASCIIByteBufferbuffer=charset.newEncoder().encode(chars);ByteBufferdirectBuffer=ByteBuffer.allocateDirect(buffer.limit());directBuffer.put(buffer);Java实用教程12.6.3Channels1.ServerSocketChannelJava.nio.channels.ServerSocketChannel与java.net.ServerSocket一样,用于创建一个监听线程来接收到来的连接,只是既不能读也不能写。ServerSocketChannel.socket()提供对底层ServerSocket的访问,因此可以设置Socket选项。这个通道可以使用ServerSocketChannel.open()工厂方法创建。ServerSocketChannelaccept()为新建立连接的客户返回java.nio.channel.SocketChannel。如果ServerSocketChannel进入阻塞模式,accept()不会返回,直到一个有连接请求到达;而在非阻塞模式,不管Socket是否为空,总是立刻返回。Java实用教程2.SocketChannelJava.nio.channels.SocketChannel在应用程序中封装了java.net.Socket并添加非阻塞模式和状态机。SocketChannel可以通过两种方法创建:SocketChannel.open()创建一个新的、无连接的SocketChannel;通过ServerSocketChannel.accept()返回的Socket,实际上有一个开放和连接的SocketChannel附加在它上面。Java实用教程3.FileChannel文件通道允许使用操作系统的文件缓冲直接进行文件传输。文件通道可以将文件区域映射到内存。MappedByteBuffer是一个专门用于直接缓冲的ByteBuffer,这个类用字节缓冲来映射一个文件。想要映射一个文件到MappedByteBuffer,必须先取得这个文件的通道(channel)。通道是某种已建立的连接,如管道(Pipe)、套接口(Socket)或文件(File)等能够完成I/O操作的对象。Java实用教程如果是文件通道,你可以通过FileInputStream(文件输入流)、FileOutputStream(文件输出流)或RandomAccessFile(随机存取文件)的getChannel方法来获得一个通道。一旦你取得这个通道,就可以通过它的map方法指明映射模式,来把你想映射的那一部分文件映射到缓冲中去。文件通道可以使用FileChannel.MapMode的任一个常数打开:只读(READ_ONLY)、私有/写时拷贝(PRIVATE)或读写(READ_WRITE)。Java实用教程【例12.5】使用文件通道打开一个文件并输出文件内容。1.分析(1)通过文件输入流对象得到通道。FileInputStreaminput=newFileInputStream(filename);FileChannelchannel=input.getChannel();(2)映射到字节缓冲。intfileLength=(int)channel.size();MappedByteBufferbuffer=channel.map(FileChannel.MapMode.READ_ONLY,0,Java实用教程(3)字符集进行解码。Charsetcharset=Charset.forName("ISO-8859-1");//CharsetDecoderdecoder=charset.newDecoder();CharBuffercharBuffer=decoder.decode(buffer);(4)输出文件内容。System.out.println(charBuffer);Java实用教程2.源程序//程序文件名为UseFchannel.javaimportjava.io.;importjava.nio.;importjava.nio.channels.;importjava.nio.charset.;classUseFchannel{publicstaticvoidmain(String[]args){try{Java实用教程Stringfilename="f.txt";FileInputStreaminput=newFileInputStream(filename);FileChannelchannel=input.getChannel();intfileLength=(int)channel.size();MappedByteBufferbuffer=hannel.map(FileChannel.MapMode.READ_ONLY,0,fileLength);Charsetcharset=Charset.forName("ISO-8859-1");//CharsetDecoderdecoder=charset.newDecoder();CharBuffercharBuffer=decoder.decode(buffer);System.out.println(charBuffer);Java实用教程}catch(Exceptione){System.out.println("Error:"+e.getMessage());}}}Java实用教程3.结果分析图12.5上一部分显示打开的文件内容,下一部分显示程序输出的内容,可以看出两者是一致的。图12.5源文件内容与程序输出的内容对比Java实用教程12.6.4Selectors非阻塞I/O围绕为多元选择通道准备的Selectors(选择器)对象构建。选择器对象保持一系列选择键,这些键在应用中可由某个事件激活。选择器本身管理键,编程人员使用键的状态管理回调来完成客户请求。构造函数如下:protectedSelector()初始化一个实例。选择器可以通过调用自带的open方法进行创建:Selectors=Selector.open();Java实用教程下面的两个方法用来返回选择键值的个数和键值集合。publicabstractintselect()throwsIOException返回键值的个数。publicabstractSetselectedKeys()返回选择器选中的键值集合。对于一个Socket通道,只有将它本身发生的事件(如监听、连接、读、写等)在选择器上进行注册,才可以被选择器识别,从而进行处理,这个注册就用到SelectionKey类。SelectionKey类包括四个注册值,将通道支持的事件注册到相应的选择器上。它还提供四个判断键值状态的方法,从而进行相应的事件处理,如表12.3所示。Java实用教程表12.3SelectionKey类的注册值及其方法注册值注册事件键值状态判断函数函数描述OP_ACCEPT接收publicbooleanisAcceptable()测试通道是否可接收OP_CONNECT连接publicbooleanisConnectable()测试通道连接完成或失败OP_READ读取publicbooleanisReadable()测试通道是否可读OP_WRITE写入publicbooleanisWritable()测试通道是否可写Java实用教程例如,接收新连接的通道应该注册为:ServerSocketChannelch=ServerSocketChannel.open();SelectionKeyacceptKey=ch.register(s,SelectionKey.OP_ACCEPT);一个读取和写入数据的通道应该注册为:SelectionKeyreadWriteKey=ch.register(s,SelectionKey.OP_READSelectionKey.OP_WRITE);当用户发送一个请求时,选择器通过返回键进行工作。//循环实现While((keysAdded=s.select())>0){Java实用教程//返回键值集合setreadyKeys=s.selectedKeys();//使用Iterator枚举IteratorI=readKeys.iterator();While(i.hasNext()){SelectionKeysk=(SelectionKey)i.next();...接收连接处理请求;}}Java实用教程具体的处理可以根据键值的状态进行,上面的“接收连接处理请求”就可以为:i.remove();if(key.isAcceptable()){...}elseif(key.isWritable()){...}Java实用教程12.6.5阻塞模式在阻塞模式下,服务器端和客户端的程序基本相同,惟一不同的是客户端为Connect方法,服务器端为Accept方法。新I/O包处理Socket的读写操作时使用java.net包中的InetSocketAddress类指定链接地址,并用前面介绍的SocketChannel类来完成实际的读写操作。InetSocketAddress类提供一个用来绑定、连接或者返回数值的远程对象。它常用的构造函数为:InetSocketAddress(Stringhostname,intport)以名字hostname和端口号port创建socket地址。Java实用教程客户端使用SocketChannel建立连接的步骤如下:(1)首先获得InetSocketAddress的对象。Stringhost="www.sohu.com.cn";InetSocketAddresssocketAddress=newInetSocketAddress(host,80);(2)打开一个到InetSocketAddress代表的主机的连接。使用SocketChannel取代以前从Socket对象的输入流来读取、向Socket的输出流写入的所有操作:SocketChannelchannel=SocketChannel.open();channel.connect(socketAddress);Java实用教程(3)发送一个HTTP请求,发送请求之前进行编码。Charsetcharset=Charset.forName("ISO-8859-1");CharsetEncoderencoder=charset.newEncoder();Stringrequest="GET/HTTP/1.0\r\n\r\n";channel.write(encoder.encode(CharBuffer.wrap(request)));Java实用教程(4)从通道中读取服务器的响应。ByteBufferbuffer=ByteBuffer.allocateDirect(1024);CharBuffercharBuffer=CharBuffer.allocate(1024);while((channel.read(buffer))!=-1){buffer.flip();decoder.decode(buffer,charBuffer,false);charBuffer.flip();System.out.println(charBuffer);buffer.clear();charBuffer.clear();}Java实用教程【例12.6】下面这个程序通过一个HTTP请求来读取站点www.xjtu.edu.cn的首页,直接输出到屏幕上,可以看见是网页的文本文件。源程序代码如下://程序文件名为ReadURL.javaimportjava.io.;importjava.net.;importjava.nio.;importjava.nio.channels.;importjava.nio.charset.;Java实用教程publicclassReadURL{publicstaticvoidmain(Stringargs[]){SocketChannelchannel=null;Stringhost="www.xjtu.edu.cn";try{//建立连接InetSocketAddresssocketAddress=newInetSocketAddress(host,80);Java实用教程Charsetcharset=Charset.forName("ISO-8859-1");CharsetDecoderdecoder=charset.newDecoder();CharsetEncoderencoder=charset.newEncoder();//分配缓冲ByteBufferbuffer=ByteBuffer.allocateDirect(1024);CharBuffercharBuffer=CharBuffer.allocate(1024);//连接channel=SocketChannel.open();channel.connect(socketAddress);//发送请求Stringrequest="GET/HTTP/1.0\r\n\r\n";channel.write(encoder.encode(CharBuffer.wrap(request)));while((channel.read(buffer))!=-1){Java实用教程buffer.flip();//解码decoder.decode(buffer,charBuffer,false);//输出charBuffer.flip();System.out.println(charBuffer);buffer.clear();charBuffer.clear();}}catch(UnknownHostExceptione){System.err.println(e);}catch(IOExceptione){System.err.println(e);Java实用教程}finally{if(channel!=null){try{channel.close();}catch(IOExceptionignored){}}}}}Java实用教程12.6.6非阻塞模式1.非阻塞客户端(1)创建可选择通道,配置成非阻塞模式并进行连接。Stringhost="192.100.100.43";InetSocketAddresssocketAddress=newInetSocketAddress(host,80);channel=SocketChannel.open();channel.configureBlocking(false);channel.connect(socketAddress);这时得到的通道channel是一个可选择通道(SelectableChannel),通过一个Selector来工作。将通道注册到一个Selector,同时声明一些事件,当事件发生时通道会通过回调执行。Java实用教程(2)创建Selector实例。Selectorselector=Selector.open();(3)通道向选择器的注册。对于SocketChannel类来说,有效的操作事件是OP_CONNECT、OP_READ和OP_WRITE,因此可以进行如下注册:channel.register(selector,SelectionKey.OP_CONNECTSelectionKey.OP_READ);Java实用教程(4)处理通道事件。当有事件在通道上发生时,Selector进行通知,然后使用一个while(selector.select()>0)循环进行处理。发出请求后得到响应的代码都放入这一段,当作读写事件进行处理。(5)加入异常处理代码。加入必要的try{...}catch(Exceptione){...}语句,并在finally代码段中加入关闭通道的代码。Java实用教程【例12.7】下面是完整的例子程序,结果是得到本机tomcat主页并显示在标准输出上。用户也可以将它输出到文件中,以方便与原网页进行比较。源程序代码如下://程序文件名为NBReadURL.javaimportjava.io.;importjava.net.;importjava.nio.;importjava.util.;importjava.nio.channels.;importjava.nio.charset.;Java实用教程publicclassNBReadURL{staticSelectorsele;publicstaticvoidmain(Stringargs[]){Stringhost="192.100.100.43";SocketChannelchannel=null;try{Java实用教程//初始化InetSocketAddresssockAddr=newInetSocketAddress(host,8080);Charsetcharset=Charset.forName("ISO-8859-1");CharsetDecoderdecoder=charset.newDecoder();CharsetEncoderencoder=charset.newEncoder();//分配缓冲ByteBufferbuf=ByteBuffer.allocateDirect(1024);CharBuffercbuf=CharBuffer.allocate(1024);//连接channel=SocketChannel.open();channel.configureBlocking(false);channel.connect(sockAddr);Java实用教程//打开选择器sele=Selector.open();channel.register(sele,SelectionKey.OP_CONNECTSelectionKey.OP_READ);//Waitforsomethingofinteresttohappenwhile(sele.select(500)>0){//得到对象SetreadyKeys=sele.selectedKeys();IteratorreadyItor=readyKeys.iterator();Java实用教程//遍历对象集while(readyItor.hasNext()){//得到键SelectionKeyk=(SelectionKey)readyItor.next();//RemovecurrententryreadyItor.remove();//得到通道SocketChannelkeyChannel=(SocketChannel)k.channel();if(k.isConnectable()){Java实用教程//完成连接if(keyChannel.isConnectionPending()){keyChannel.finishConnect();}//发送请求Stringrequest="GET/index.html\r\n\r\n";keyChannel.write(encoder.encode(CharBuffer.wrap(request)));}elseif(k.isReadable()){Java实用教程//读取数据keyChannel.read(buf);buf.flip();//解码decoder.decode(buf,cbuf,false);//显示cbuf.flip();System.out.print(cbuf);//清除缓冲buf.clear();cbuf.clear();}else{Java实用教程System.err.println("Ooops");}}}}catch(UnknownHostExceptione){System.err.println(e);}catch(IOExceptione){System.err.println(e);}finally{if(channel!=null)Java实用教程{try{channel.close();}catch(IOExceptionignored){}}}System.out.println();}}Java实用教程2.非阻塞服务器使用新I/O包实现的非阻塞Web服务器,不必为每个连接都提供一个线程就可以实现Web服务器的功能。非阻塞服务器程序编写的步骤如下:(1)创建接收通道,配置非阻塞模式并绑定到InetSocketAddress对象。ServerSocketChannelchannel=ServerSocketChannel.open();channel.configureBlocking(false);InetSocketAddressisa=newInetSocketAddress(port);channel.socket().bind(isa);Java实用教程(2)创建Selector实例。Selectorselector=Selector.open();(3)注册事件。服务器端需要注册的是OP_ACCEPT键值:channel.register(selector,SelectionKey.OP_ACCEPT);(4)处理通道事件。当有事件在通道上发生时,Selector进行通知,然后使用一个while(selector.select()>0)循环进行处理。发出请求得到响应的代码都放入这一段,当作读写事件进行处理。Java实用教程(5)添加异常处理代码。加入必要的try{...}catch(Exceptione){...}语句,并在finally代码段中加入关闭通道的代码。可以看出非阻塞模式下服务器和客户端编程的步骤都是一致的,只是有些步骤下编写的代码有所不同。Java实用教程【例12.8】给出一个基本的单线程的服务器,对每一个响应都发回一段文字信息来表示时间。源程序代码如下://程序文件名为Server.javaimportjava.io.;importjava.net.;importjava.nio.;importjava.nio.channels.;importjava.util.;publicclassServer{Java实用教程privatestaticintport=4321;publicstaticvoidmain(Stringargs[])throwsException{Selectorselector=Selector.open();ServerSocketChannelchannel=ServerSocketChannel.open();channel.configureBlocking(false);InetSocketAddressisa=newInetSocketAddress(port);channel.socket().bind(isa);//注册channel.register(selector,SelectionKey.OP_ACCEPT);while(selector.select()>0){Java实用教程SetreadyKeys=selector.selectedKeys();IteratorreadyItor=readyKeys.iterator();while(readyItor.hasNext()){SelectionKeykey=(SelectionKey)readyItor.next();readyItor.remove();ServerSocketChannelkeyChannel=(ServerSocketChannel)key.channel();ServerSocketserverSocket=keyChannel.socket();Socketsocket=serverSocket.accept();//返回时间Java实用教程PrintWriterout=newPrintWriter(socket.getOutputStream(),true);Datenow=newDate();out.println("Hello,nowtimeis:"+now);out.close();}//EndofWhile}//EndofWhile}//Endofmain}Java实用教程为了服务器与客户端能够进行通信,对例12.7的客户端程序进行修改,将InetSocketAddress对象sockAddr中的端口号改成4321,使得客户端请求的端口号与此服务器监听的端口号一致,即将InetSocketAddresssockAddr=newInetSocketAddress(host,8080);改为InetSocketAddresssockAddr=newInetSocketAddress(host,4321);然后重新编译,生成类文件。启动两个命令提示符,其中一个为运行命令“javaServer”,另一个为键入命令“javaNBReadURL”,可以看见如图12.6的通信结果。客户端显示服务器发送的一段时间信息。如果希望在服务器端显示内容,还需修改服务器程序,注册服务器通道的读、写事件。Java实用教程图12.6非阻塞模式下的通信输出Java实用教程习题1.给出字符串,熟悉URLEncoder和URLDecoder类的规范。2.从天网主页http://e.pku.edu.cn检索包含“网络”一词的文件。3.使用HttpURLConnection对象打开网页并输出到文件中。4.使用文件通道将例12.6的程序输出改成输出到文件中。5.编写非阻塞模式下的Socket通信。Java实用教程第13章Servlet技术13.1Servlet概述13.2Servlet生命周期13.3使用Servlet13.4Applet与Servlet通信习题Java实用教程13.1Servlet概述Servlet是用Java编写的且协议和平台都独立的服务器端的组件。与客户端组件Applet相对应。Servlet扩展了面向请求/响应的服务器的模块,使用平台专用的API进行服务器端的编程。Servlet为服务器和基于Web的客户之间的通信提供了一条更为简单的途径。它的特殊用途包括:(1)允许用户之间的合作。一个Servlet可以同时并发处理大量的请求,而且可以同步请求,因此使Servlets能够支持像在线会议这样的系统。Servlets能够并发地服务多个客户。Java实用教程(2)转发请求。Servlets能够转发请求到其它的服务器和Servlets,因此Servlets能够被用来在多个镜像同一个内容的服务器之间来平衡负载,在多个服务器上根据任务类型或者组织边界分割单一的逻辑服务。Java实用教程13.2Servlet生命周期图13.1Servlet的生命周期·þÎñÆ÷·þÎñÆ÷´¦ÀíÓû§ÇëÇóÔØÈëÏú»Ù·þÎñÆ÷Servlet´úÂëServlet´úÂë¿Í»§¿Í»§Servlet´úÂëJava实用教程1.初始化Servlet当服务器载入一个Servlet时,服务器运行Servlet的init方法。初始化在客户请求被处理和Servlet被销毁之前完成。Java实用教程2.Servlet_Client交互初始化成功后,HTTPServlet调用Service方法处理客户请求,Service方法将每个请求分配到处理这个请求的方法,从而支持标准的HTTP客户请求。HttpServlet类中的方法处理客户请求时使用以下两个参数:(1)HttpServletRequest对象:封装了从客户来的数据,主要提供了访问初始请求数据的方法和字段;访问客户数据时使用getParameter方法得到一个已命名参数的值。(2)HttpServletResponse对象:封装了对客户的响应。使用getWriter方法返回文本数据给客户(可以以HTML网页的形式表现出来)。Java实用教程Service方法支配的HTTP请求如表13.1所示。表13.1Service方法支配的HTTP请求Service方法处理的HTTP请求doGet处理GET、条件GET和HEAD请求doPost处理POST请求doPut处理PUT请求deDelete处理DELETE请求Java实用教程通常,编写的Servlet应该重载处理它支持的HTTP交互的方法。如果出错,这些方法返回一个BAD_REQUEST(400)错误。当Servlet收到OPTIONS请求时,HttpServlet的Service方法调用doOptions方法。默认的doOptions的实现自动地决定了支持何种HTTP选项和返回信息。HTTPServlets通常能够并发地服务多个客户。如果Servlet中的这个方法对于客户访问共享资源是可行的,那么你可以通过创建在某一时刻只能处理一个客户请求的Servlet来处理并发。Java实用教程3.销毁ServletServlet一直运行直到服务器销毁它们,比如在系统管理员的要求下。当一个服务器销毁一个Servlet时,服务器运行Servlet的Destroy()方法。方法只运行一次,服务器将不再运行Servlet,直到服务器重新载入和重新初始化Servlet。Java实用教程13.3使用Servlet13.3.1编写Servlet【例13.1】在客户端填写“用户注册信息”网页,并将此网页提交到后台服务器端Servlet,服务器端Servlet程序给予响应,并以网页的形式按行输出用户提交的基本信息。1.客户端客户端是一个“用户注册信息”的HTML网页,如图13.2所示。用户输入个人信息,点击“确定”按钮,将表单数据提交到服务器,然后等待服务器的响应。Index.html源文件代码如下:Java实用教程用户注册信息收集

用户注册信息
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是表单中的元素标签和命名,可以看到除去“确定”和“清空”,其它的元素标签在第三栏都有一个对应的名字,Servlet通过这些名字获得用户在界面上输入的值,而用户单击“确定”按钮时,表单内容就提交到action属性指定的Servlet。Java实用教程表13.2表单元素标签及命名元素标签类型标签命名姓名textname身份证号textnumber性别radiosex职业selectjob个性化宣言textareata确定submit\清空reset\Java实用教程2.服务器端服务器端Servlet收集用户界面输入的数据(见图13.3),然后按行返回这些内容,结果如图13.4所示。注意传输过程中中文字符可能会有出错情况,因此再添加一个转换字段,使得Servlet能够正确打印输出。//程序文件名:UserServlet.javapackageuser;importjava.io.;importjavax.Servlet.;importjavax.Servlet.http.;publicclassUserServletextendsHttpServlet{Java实用教程Stringname,number,sex,job,ta;publicvoidinit()throwsServletException{super.init();name=newString();number=newString();sex=newString();job=newString();ta=newString();}//解决中文转换问题publicStringparseChinese(StringinStr){Java实用教程Strings=null;bytetemp[];if(inStr==null){//System.out.println("Warn:Chinesenullfounded!");returnnewString("");}try{temp=inStr.getBytes("iso-8859-1");s=newString(temp);}catch(UnsupportedEncodingExceptione){Java实用教程System.out.println(e.toString());}returns;}publicvoiddoPost(HttpServletRequestreq,HttpServletResponseres)throwsServletException,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;charset=GB2312");PrintWriterout=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.4Servlet返回信息Java实用教程13.3.2编译、配置Servlet安装的Java包是没有带Servlet的JAR文件,所以将D:\ApacheTomcat4.0\common\lib目录下的Servlet.jar配置到路径包的安装路径下库的扩展目录中,编译时会自动连接库,如本书配置到的目录为D:\j2sdk1.4.0_01\jre\lib\ext。在命令行提示符下键入命令javacUserServlet.java编译文件,生成类UserServlet.class。Java实用教程Servlet是服务器端组件,所以必须配置到服务器端。对于Tomcat4.0服务器,将index.html配置到物理路径D:\ApacheTomcat4.0\webapps\ROOT\user目录下,对应的网络路径就是http://192.100.100.43:8080/user/index.html;将UserServlet配置到物理路径下的D:\ApacheTomcat4.0\webapps\examples\WEB-INF\classes\user目录下,对应的网络地址就是http://192.100.100.43:8080/examples/Servlet/user.UserServlet。这些配置信息由index.html中的Action属性标明。Java实用教程如果希望能够配置到根目录下,则在开始->程序->ApacheTomcat4.0->Configuration中单击EditServerConfiguration,然后找到行:删除第二个,将以上语句变成:Java实用教程将机器重启动,使得配置文件生效,并在D:\ApacheTomcat4.0\webapps\ROOT\WEB-INF路径下建立classes目录,然后将UserServlet.java源文件中的语句行packageuser;去掉,重新编译成.class类文件并放入此目录,则action属性对应的网络地址为http://192.100.100.43:8080/Servlet/UserServletJava实用教程13.4Applet与Servlet通信Applet与Servlet的通信过程的基本原理相当于HTML网页的POST请求。首先两者之间建立一个连接,使用URLConnection类对象打开连接后,Applet将请求发送给Servlet,Servlet处理请求并返回处理结果。注意,发送请求数据时一定用URLEncoder类的Encode方法进行格式编码,在Servlet端还需用URLDecoder类的Decode方法进行格式解码。在HTTP协议中POST请求是以参数名=参数值的方式自动进行URL编码后传送的,编程中要手工实现,例如名-值对Java实用教程qry=SELECTnumber,code,scorefromchengjiWHEREcode='3001'进行URL编码如下:Stringqry=URLEncoder.encode("qry","UTF-8")+"="+URLEncoder.encode(qryString,"UTF-8");建立连接时,注意将DbServlet配置到路径D:\ApacheTomcat4.0\webapps\ROOT\WEB-INF\classes下。Java实用教程Stringstr="http://192.100.100.43:8080/Servlet/DbServlet";URLurlName=newURL(str);打开连接。URLConnectionuc=urlName.openConnection();设置参数。uc.setDoOutput(true);uc.setDoInput(true);uc.setUseCaches(false);Java实用教程uc.setRequestProperty("Content-type","application/x-www-form-urlencoded");得到数据流发送格式转换后的POST请求。DataOutputStreamdos=newDataOutputStream(uc.getOutputStream());dos.writeBytes(qry);在DbServlet中接收数据并进行解码。Stringqry=req.getParameter("qry");qry=URLDecoder.decode(qry,"UTF-8");Java实用教程【例13.2】编写Applet和Servlet交互的程序,使得用户在Applet界面(见图13.5)上输入数据库查询语句,单击“查询”按钮后,后台Servlet接收请求,对后台数据库进行查询,并将查询结果返回到Applet界面的文本区域内。图13.5Applet用户界面Java实用教程图13.6Applet和Servlet交互原理图Êý¾Ý¿âSQL²éѯResultSet¶ÔÏóURLConnection´ò¿ªÁ¬½Ó£¬·¢ËÍÇëÇóÁ÷¶ÔÏó½ÓÊÕ·µ»Ø½á¹ûJavaAppletJavaServletJava实用教程13.4.1Servlet文件首先书写查询数据库的Servlet文件,编译通过后配置到上面提到的路径。//程序文件名DbServlet.javaimportjavax.Servlet.;importjavax.Servlet.http.;importjava.util.;importjava.sql.;importjava.io.;importjava.net.;Java实用教程publicclassDbServletextendsHttpServlet{publicvoiddoPost(HttpServletRequestreq,HttpServletResponseres)throwsIOException,ServletException{PrintWriterout=res.getWriter();res.setContentType("text/html;charset=GB2312");//得到Applet请求参数,解码后输出Stringqry=req.getParameter("qry");qry=URLDecoder.decode(qry,"UTF-8");out.println(qry);ConnectiondbCon=null;tryJava实用教程{//同数据库建立连接Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");StringdbURL="jdbc:odbc:STU";dbCon=DriverManager.getConnection(dbURL,"","");PreparedStatementp=dbCon.prepareStatement(qry);ResultSetrs=p.executeQuery();//输出查询结果while(rs.next()){out.print(rs.getString(1));out.print(rs.getString(2)+"");out.println(rs.getInt(3));}Java实用教程}catch(Exceptione){out.println("读写数据库出错:"+e.getMessage());}finally{try{dbCon.close();out.close();}catch(Exceptione)Java实用教程{out.println("关闭数据库连接出错:"+e.getMessage());}}}};Java实用教程13.4.2Applet文件编写与Servlet通信的Applet文件。//程序文件名DbApplet.javaimportjava.awt.;importjava.applet.;importjava.awt.event.;importjava.io.;importjava.net.;publicclassDbAppletextendsAppletimplementsActionListener{TextFieldtfQuery;Java实用教程TextAreataResults;ButtonbtnExecute;URLchatURL;publicvoidinit(){Panelpa=newPanel();pa.setLayout(newFlowLayout(FlowLayout.LEFT));pa.add(newLabel("查询串:"));tfQuery=newTextField("SELECTnumber,code,scorefromchengjiWHEREcode='3001'",50);Java实用教程pa.add(tfQuery);btnExecute=newButton("查询");btnExecute.addActionListener(this);pa.add(btnExecute);add("North",pa);taResults=newTextArea(30,60);add("Center",taResults);chatURL=getCodeBase();}publicvoidactionPerformed(ActionEventevt){Java实用教程Stringlbl=evt.getActionCommand();if(lbl.equals("查询")){StringqryString=tfQuery.getText();try{//查询串编码Stringqry=URLEncoder.encode("qry","UTF-8")+"="+URLEncoder.encode(qryString,"UTF-8");//打开到DbServlet的连接Stringstr="http://192.100.100.43:8080/Servlet/DbServlet";Java实用教程URLurlName=newURL(str);URLConnectionuc=urlName.openConnection();uc.setDoOutput(true);uc.setDoInput(true);uc.setUseCaches(false);uc.setRequestProperty("Content-type","application/x-www-form-urlencoded");//获得输出流DataOutputStreamdos=newDataOutputStream(uc.getOutputStream());Java实用教程//发送编码的查询串dos.writeBytes(qry);dos.close();//获取结果,输出InputStreamReaderin=newInputStreamReader(uc.getInputStream());intchr=in.read();while(chr!=-1){taResults.append(String.valueOf((char)chr));chr=in.read();}Java实用教程in.close();}catch(MalformedURLExceptione){taResults.setText(e.toString());}catch(IOExceptione){taResults.setText(e.toString());}}}}Java实用教程13.4.3HTML文件最后编写HTML文件,用户最好将它转换成使用插件的文件,使用插件的文件具有较好的应用性。

Java实用教程13.4.4结果显示本例中用到的表为STU配置下的Chengji表,部分记录如图13.7所示。查询串分别为:SELECTnumber,code,scorefromchengjiWHEREcode='2001'SELECTnumber,code,scorefromchengjiWHEREcode='1002'而查询结果如图13.8所示。对照Chengji表,得出查询结果完全正确。Java实用教程图13.7STU库中的Chengji表Java实用教程图13.8查询结果的输出Java实用教程习题1.编写Servlet程序,进行数据库访问,将数据库结果以表格的形式显示在HTML网页上。2.编写Applet和Servlet的交互程序,Applet请求打开一个文本文件,Servlet接收文件的路径和名称,返回文本文件的内容。在Applet界面上的文本框内输入文件路径以及名称,单击“请求”按钮,得到Servlet的响应,返回的内容输出到Applet界面上的文本区域内。设计具体界面时可参考图13.9。Java实用教程图13.9用户界面Java实用教程第14章Java读写XML技术14.1XML简介14.2SAX接口解析XML14.3DOM接口解析XML习题Java实用教程14.1XML简介14.1.1XML定义XML是SGML一个简化而严格的子集,特别是为Web应用设计的,具有可扩展性、结构性和可检验性。●可扩展性指用户可以根据需要自定义新的标识以及属性名,更好地从语义上修饰数据。●结构性指XML文件结构可以嵌套,也可以复杂到任意程度。●可校验性指XML文件文件可以包括一个语法描述,应用程序可以通过语法描述对此文件进行结构检验。Java实用教程14.1.2XML分类图14.1XML相关标准的体系结构(»ù´¡±ê×¼)XML(ÔªÓïÑÔ±ê×¼)HTTPURI/URLUnicode(ÍâΧ±ê×¼)xInclude¡­(ºËÐıê×¼)RDF¡­(ÄÚÈÝÃèÊö±ê×¼)cXML¡­(Ó¦Óñê×¼)SchemaDOM¡­(²Ù×÷±ê×¼)CSSXSLXSLT¡­(ÑùʽÓëÁ´½Ó±ê×¼)Java实用教程1.元语言标准用来描述标准的元语言,即XML标准。XML相关标准主要分为三类,分别是元语言标准、基础标准和应用标准。Java实用教程2.基础标准为XML进一步实用化制定的标准,共分为五类:外围标准、核心标准、操作标准、样式与链接标准、内容描述标准。(1)外围标准指Internet网络上统一应用的标准:●HTTP协议采用请求/应答方式,客户端向服务器提交请求方式、URI、协议版本、客户端信息等,服务器向客户端返回状态信息、实体信息以及实体内容等。●URI/URL指资源定位符,用来在网络上实现快速资源定位。●Unicode指Internet网上统一传输数据的标准编码。Java实用教程(2)核心标准是XML核心的标准。(3)操作标准为XML文档的处理提供有效的方法与规则,DOM是与平台无关的,提供一个编程接口。Schema是对DOM的补充,提供一种更为严格的描述XML文档的结构、属性、数据类型等的方法。Java实用教程(4)样式与链接标准。●CSS是XML文档显示的样式标准。●XSL标准可将XML文档形成树状结构,采用元素节点匹配的方式进行转换,因而该标准提供转换和显示的标准。●XSLT标准是从XSL中分离出来的,是XML文档的转换标准,可以将XML文档转换为HTML文档并进行显示处理。(5)内容描述标准。RDF(ResourseDescriptionFormat)采用XML语法格式处理元数据的应用,是为描述图像文档和它们之间的相互关系定义的一个简单数据模型,为进行资源描述定义了资源描述的规则。Java实用教程3.应用标准XML标准是Internet时代的ASCII标准,主要针对具体的领域进行应用,如cXML是指电子商务XML应用标准、voiceXML指语音XML等。Java实用教程14.1.3XML文档的书写图14.2XML文档举例王飞理工大学2663457教授Java实用教程14.1.4XML文档的解析图14.3XML文档的处理过程XMLÓ¦ÓóÌÐòSAX½Ó¿ÚDOM½Ó¿ÚXML·ÖÎöÆ÷XMLÎĵµJava实用教程14.2SAX接口解析XML14.2.1解析的步骤(1)创建SAX解析工厂的实例。SAXParserFactoryspf=SAXParserFactory.newInstance();(2)创建一个SAX解析器。SAXParsersp=spf.newSAXParser();(3)得到SAX的处理器(处理器由用户自己编写实现)。SAXHandlerhandler=newSAXHandler();(4)使用用户创建的处理器,解析器解析文件。sp.parse(newInputSource(reader),handler);Java实用教程14.2.2相关类在J2sdk1.4中的SAX版本为2.0,它提供DefaultHandler(org.xml.sax.helpers.DefaultHandler)接口,通过这个接口实现自己的解析器。接口中需要实现的解析函数为:publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)throwsSAXException读取XML数据的节点元素开始时触发,需要实现这个方法进行标记元素的名字的操作。Java实用教程publicvoidendElement(Stringuri,StringlocalName,StringqName)throwsSAXException处理节点元素终止时触发,可以添加代码来将节点数据进行存储。publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXException处理节点之间的数据,可以添加代码来读取节点间的数据值。Java实用教程【例14.1】编写一个SAX处理器,对14.1节中的person.xml进行解析,输出XML文件节点的标签和节点的值。分析:类SAXHandler是一个处理类,实现这个DefaultHandler接口时覆盖了上述三个方法,将读取的节点标签和节点的值存入到Hashtable对象中。类中提供了一个方法,返回读取的名-值对的Hashtable对象。输出结果如图14.4所示。源程序代码如下://程序文件名为Parse.javaimportjava.io.;importjava.util.Hashtable;importorg.w3c.dom.;Java实用教程importorg.xml.sax.;importjavax.xml.parsers.SAXParser;importjavax.xml.parsers.SAXParserFactory;importorg.xml.sax.helpers.;publicclassParse{publicstaticvoidmain(String[]args){try{Java实用教程Filefile=newFile("person.xml");FileReaderreader=newFileReader(file);//创建解析工厂实例SAXParserFactoryspf=SAXParserFactory.newInstance();//创建解析器SAXParsersp=spf.newSAXParser();//创建处理类实例SAXHandlerhandler=newSAXHandler();//解析sp.parse(newInputSource(reader),handler);HashtablehashTable=handler.getTable();//输出数据Java实用教程System.out.println("教师信息表");System.out.println("姓名:"+(String)hashTable.get(newString("name")));System.out.println("学院:"+(String)hashTable.get(newString("college")));System.out.println("电话:"+(String)hashTable.get(newString("telephone")));System.out.println("职称:"+(String)hashTable.get(newString("title")));}catch(Exceptione){System.out.println(e.getMessage());}}};Java实用教程//自定义处理类classSAXHandlerextendsDefaultHandler{privateHashtabletable=newHashtable();privateStringcurrentElement=null;privateStringcurrentValue=null;publicHashtablegetTable(){returntable;}//覆盖startElement方法,取出节点标签publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes){Java实用教程currentElement=qName;}//覆盖characters方法,取出节点值publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXException{currentValue=newString(ch,start,length);}//覆盖endElement方法,放入HashtableJava实用教程publicvoidendElement(Stringuri,StringlocalName,StringqName)throwsSAXException{if(currentElement.equals(qName))table.put(currentElement,currentValue);}};Java实用教程图14.4解析person.xml文件后输出结果Java实用教程14.3DOM接口解析XML14.3.1解析的步骤1.从DOM接口写XML的步骤(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)得到ROOTELEMENT对象;(5)得到单个ELEMENT节点;(6)得到ELEMENT创建节点的值。Java实用教程14.3.2相关类1.DocumentBuilderFactory类publicabstractclassDocumentBuilderFactoryextendsObject定义工厂API,使得应用程序得到解析器从XML文档中产生的DOM对象树。publicstaticDocumentBuilderFactorynewInstance()throwsFactoryConfigurationError得到DocumentBuilderFactory的一个实例,这个实例某个时刻只能用于一个线程。publicabstractDocumentBuildernewDocumentBuilder()throwsParserConfigurationException使用当前配置的方法创建一个新的DocumentBuilder的实例。Java实用教程2.DocumentBuilder类publicabstractclassDocumentBuilderextendsObject定义从XML文档得到DOM文档的API。publicabstractDocumentnewDocument()得到DOM文档对象的一个新实例,用来构建DOM树。publicDocumentparse(Filef)throwsSAXException,IOException解析给定的XML文档f,返回DOM文档对象。Java实用教程3.Document类publicinterfaceDocumentextendsNodeDocument接口代表整个XML文档。publicElementcreateElement(StringtagName)throwsDOMException创建指定的类型的元素tagName。publicTextcreateTextNode(Stringdata)使用给定的data字符串创建节点元素的值。Java实用教程4.Element类publicinterfaceElementextendsNodeElement接口代表XML文档中的一个元素。publicNodeListgetElementsByTagName(Stringname)返回给定的name元素下面的所有节点列表,以前向遍历的方式给出。Java实用教程5.NodeList类NodeList接口给出一个节点集合,有以下两个方法:publicintgetLength()返回节点的个数。publicNodeitem(intindex)返回第index个节点。Java实用教程6.Node类Node接口是整个文档对象模型中最主要的数据类型,它表示文档树中单一的节点。NodegetFirstChild()返回节点的第一个孩子节点。StringgetNodeValue()返回叶子节点的值。Java实用教程14.3.3实例【例14.2】在用户界面(见图14.5)上输入个人信息后,单击“确定”按钮,程序收集用户信息,存成文档user.xml并显示如下。单击“显示”按钮,读取user.xml文件,将节点标签和对应的节点值显示在文本区域内。王飞111122197904290902军队海纳百川,有容乃大;壁立千仞,无欲则刚Java实用教程1.程序源文件//程序文件名UsePanel.javaimportjava.awt.;importjava.awt.event.;importjava.applet.;importjava.applet.Applet;importjava.io.;importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importorg.w3c.dom.;Java实用教程publicclassUsePanelextendsAppletimplementsActionListener{LabellblName,lblNumber,lblSex,lblJob,lblText;TextFieldtfName,tfNumber;CheckboxchMale,chFemale;CheckboxGroupc;TextAreataText;ChoicechJob;ButtonbtnOk,btnDisplay;Panelp1,p2,p3,p4,p5,p6,p7,p8,p9;StringstrName,strNumber,strSex,strJob,strText;publicvoidinit(){Java实用教程//初始化界面对象lblName=newLabel("姓名:");lblNumber=newLabel("身份证号:");lblSex=newLabel("性别");lblJob=newLabel("职业");lblText=newLabel("个性化宣言:");tfName=newTextField(23);tfNumber=newTextField(20);taText=newTextArea(10,20);c=newCheckboxGroup();chMale=newCheckbox("男",c,true);chFemale=newCheckbox("女",c,false);chJob=newChoice();Java实用教程chJob.add("计算机业");chJob.add("医生");chJob.add("教师");chJob.add("军队");btnOk=newButton("确定");btnDisplay=newButton("显示");p1=newPanel();p2=newPanel();p3=newPanel();p4=newPanel();p5=newPanel();p6=newPanel();Java实用教程p7=newPanel(newBorderLayout());p8=newPanel();p9=newPanel(newBorderLayout());//设置界面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(newBorderLayout());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(newFlowLayout(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);//添加监听事件btnOk.addActionListener(this);btnDisplay.addActionListener(this);Java实用教程btnDisplay.setEnabled(false);strName=newString();strNumber=newString();strSex=newString();strJob=newString();strText=newString();}publicvoidactionPerformed(ActionEventevt){Stringarg=evt.getActionCommand();//收集用户信息并写入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{//创建新的文档对象DocumentBuilderFactoryJava实用教程DocumentBuilderdb=dbf.newDocumentBuilder();Documentdoc=db.newDocument();//创建元素Elementroot=doc.createElement("UserData");ElementeName=doc.createElement("Name");ElementeNumber=doc.createElement("Number");ElementeSex=doc.createElement("Sex");ElementeJob=doc.createElement("Job");ElementeText=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.appendChild(doc.createTextNode("\n"+strSex+"\n"));eJob.appendChild(doc.createTextNode("\n"+strJob+"\n"));eText.appendChild(doc.createTextNode("\n"+strText+"\n"));Java实用教程//创建文件对象Filef=newFile("user.xml");FileOutputStreamfOut=newFileOutputStream(f);//初始化xml文件fOut.write("\n".getBytes());//写入文件fOut.write(root.toString().getBytes());fOut.flush();fOut.close();btnDisplay.setEnabled(true);}catch(Exceptione){Java实用教程System.out.println(e.getMessage());}}//读取XML文件并输出到文本区域elseif(arg.equals("显示")){try{//得到XML文档对象DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();DocumentBuilderdb=dbf.newDocumentBuilder();Documentdoc=db.parse("user.xml");Elementroot=doc.getDocumentElement();//获取叶子节点值Java实用教程strName=root.getElementsByTagName("Name").item(0).getFirstChild().getNodeValue().trim();strNumber=root.getElementsByTagName("Number").item(0).getFirstChild().getNodeValue().trim();strSex=root.getElementsByTagName("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身份证号:"+strNumber+"\n性别:"+strSex+"\n职业:"+strJob+"\n个性化宣言:\n"+strText);}catch(Exceptione){System.out.println(e.getMessage());}}}publicstaticvoidmain(Stringargs[]){Java实用教程Framef=newFrame("收集用户界面");//关闭窗口退出程序f.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEventevt){System.exit(0);}});//定义类实例UsePanelp=newUsePanel();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实用教程习题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所示。


  • 编号:1701027096
  • 分类:教师培训
  • 软件: wps,office Excel
  • 大小:966页
  • 格式:xlsx
  • 风格:其他
  • PPT页数:7171625 KB
  • 标签:

广告位推荐

相关教师培训更多>