canvas教程

经典JAVA教程(入门到精通)

字号+ 作者:H5之家 来源:H5之家 2015-11-19 11:50 我要评论( )

Java实用教程 全 新计 算 机 应 用 技 术 丛 书JavaJava实用教程薛 亮 编著西安电子科技大学出版社 http://www.xduph.comJava实用教程目 录第1章 Java环境及配置

经典JAVA教程(入门到精通)


Java实用教程 全 新计 算 机 应 用 技 术 丛 书

Java

Java

实用教程
薛 亮 编著

西安电子科技大学出版社

Java实用教程

目 录
第1章 Java环境及配置 第2


章 Java基本语法 第3章 类和接口 第4章 Java Applet 第5章 Java图形处理 第6章 Java用户界面技术 第7章 异常、事件和多线程机制 第8章 输入输出技术 第9章 Java数据库技术 第10章 Java安全技术 第11章 Java网络技术(一) 第12章 Java网络技术(二) 第13章 Servlet技术 第14章 Java读写XML技术

Java实用教程

第1章Java环境及配置
1.1 Java概述
1.2 Java语言的特点 1.3 Java应用分类 1.4 JDK包的下载与安装 1.5 Java环境配置 1.6 例子程序 习 题

Java实用教程

1.1 Java 概 述
Java是一种编程语言,它提供了一个同时用于程序开发、 应用和部署的环境。Java语言主要定位于网络编程,使得程 序可以最大限度地利用网络资源。

Java实用教程

1.2 Java 语 言 的 特 点
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.3 Java 应 用 分 类
1. 应用程序 典型的通用程序可以在具备Java运行环境的设备中独立运 行,它又分为: GUI应用程序:即图形用户界面程序,可实现丰富的输入 界面和输出显示。 命令行程序:无需界面,只需在命令行下运行,运行结果 只在后台发生变化,可以将输出存放到文件中。

嵌入式应用程序:Java语言的平台独立性决定了它可以嵌 入到不同的设备中,且只需具备必要的运行环境即可。

Java实用教程 2. Servlets服务器端应用程序 服务器端的应用程序用来收集客户端的数据输入,对数据 进行处理之后,返回相应的响应给客户。它主要用来实现与客 户端的交互。

Java实用教程 3. Applets小应用程序 Applets应用于网络上,嵌入在HTML网页中,支持Java的 浏览器都可以对它进行解释并运行。通常通过一个HTML标签 <APPLET></ APPLET >来识别并运行Applets。小应用程序的

类在服务器端,当浏览器显示网页时,它随之下载到本地,
由本地的浏览器载入运行。

Java实用教程

1.4 JDK包的下载与安装
Java Develop Kit简称为JDK,是Sun公司免费发行的软件包,

可以从Sun网站免费下载,也可以从其它国
内地址下载。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.5 Java 环 境 配 置
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,命令行提示符下输 出字符串“Hello World”。源代码如下: //程序文件名称为HelloWorld.java public class HelloWorld

{
public static void main(String args[]) { System.out.println("Hello World"); }

}

Java实用教程 用记事本或者专用的编辑工具如EditPlus等进行编辑,并将 文件存为HelloWorld.java。建议使用像EditPlus这样的编辑软件, 可使得代码更加清晰且风格良好。

运行“开始”菜单→程序→附件→命令提示符,载入命令 行程序,在命令行状态下,进入源程序所在的目录,图1.6所示 的例子程序的目录在“E:\_Work\Java\sample”下,然后键入命令 “javac HelloWorld.java”。若编译不通过,会产生错误提示。若 编译通过,则没有任何提示,同时进入命令行等待状态,如图 1.6所示。这时,命令行虽然没有提示,但在源程序的路径下生 成一个新的文件为HelloWorld.class。这个.class文件就是编译后 生成的类文件,运行此文件,需在命令行状态中键入命令“java HelloWorld”,然后按回车键,此时程序就会运行并输出“Hello World”。输出完毕,立即退出程序,进入命令行等待状态,如 图1.7所示。

Java实用教程

图1.6 编译源程序HelloWorld

Java实用教程

图1.7 运行HelloWorld应用程序

Java实用教程

这里用到的命令Javac和Java都是JDK软件包自带的。从
JDK安装路径的bin目录下可以看到javac.exe,这是编译程序, 源程序编译通过后就生成.class文件;而Java.exe就是载入类的 运行程序,运行时根据源程序的指令要求产生正确的输出或结 果。如果没有进行环境配置,直接编译或者运行Java源程序,

系统会提示找不到这些命令,所以必须进行环境配置后再使用。

Java实用教程 【例1.2】小应用程序的例子。输出“Hello World!”,如 图1.8所示。源程序代码如下:
//程序文件名称为HelloApplet.java

import java.awt.Graphics;
import java.applet.Applet; public class HelloApplet extends Applet { public void paint (Graphics g ) { g.drawString ("Hello World!",50,25); }

}

Java实用教程

小应用程序代码书写和编译完成后,无法独立运行,需要
一个载体或者容器。下面的HTML网页代码就是小应用程序载 入的容器。
<!-程序文件名称为HelloApplet.html --> <HTML> <HEAD> <TITLE>

HTML Test Page
</TITLE> </HEAD>

Java实用教程
<BODY> HelloApplet will appear below in a Java enabled browser.<BR> <APPLET CODEBASE = "." CODE = "HelloApplet.class" NAME = "TestApplet" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = middle > </APPLET> </BODY> </HTML>

Java实用教程

图1.8 Applet显示“Hello World!”

Java实用教程

习 题
1. 简述Java的特点。 2. 简述Java的分类情况。 3. 进行Java环境的安装和配置。 4. 编写应用程序,屏幕上输出“欢迎来到Java世界!”。 5. 编写Applet,输出“欢迎来到Java世界!”。

Java实用教程

第2章 Java基本语法
2.1 Java程序的构成 2.2 数据类型、变量和常量

2.3 运算符和表达式
2.4 流程控制 2.5 数组的使用 习 题

Java实用教程

2.1 Java程序的构成
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 注释语句

import java.apple t.*; ? ? import java.awt.* ; ? 引入包 import java.awt.e vent.*;? ?
public class WelcomeApplet extends Applet implements ActionListener 主类类头 {

Java实用教程
Label lblName; ? ? TextField txtName;? 属 性 TextField txtDisp; ? ?

public void init() ? ? { ? lblNam e ? new Label( 请输入您的名字" );? " ? txtN am e ? new TextField(8); ? txtD isp ? new TextField(20); ? ? init方法 add(lblName); ? ? add(txtName); ? add(txtDisp); ? ? txtN am e.addAct ionListener(this); ? } ?

Java实用教程
public void actionPerf orm ed(Acti onEvent e) ? ? { actionPerformed 方法 txtD isp.setText(txtNam e. getText() ? " 欢迎你来到Java世界" );? ? ? ?

Java实用教程
public static void m ain(String args[]) ? ? { ? Fram ef ? new Frame( 欢迎" ); " ? ? f.addWindowListener(new WindowAdap ter()){ ? public void windowClosing(WindowEvent evt) ? ? { ? Sy stem.exi t(0); ? ? } ? ? } ? main主方法 ? ; ? Welcom eApp a ? new Welcom eApp let let(); ? ? a.init(); ? f.add("Center", a); ? ? f.setSize(400,300); ? f.show(); ? ? a.start(); ? ? } ?

Java实用教程

图2.1 程序界面

Java实用教程 2.1.2 物理构成 Java源程序物理上由三部分构成,分别为语句、块和空白。 (1) 语句指一行以分号“;”结束的语句。 (2) 块指用括号对{}界定的语句序列,块可以嵌套使用。 (3) 空白指语句之间、块内部或者块之间的空白行。空白 不影响Java源程序的编译和运行,适当地运用空白,可以形成 良好的代码风格。

Java实用教程 在例1.1中, Label lblName; TextField txtName; TextField txtDisp; 都是语句,而 { lblName = new Label("请输入您的名字:"); txtName = new TextField(8); txtDisp = new TextField(20); add(lblName); add(txtName); add(txtDisp); txtName.addActionListener(this); } 是块,语句之间、块之间或块内部的空行都为空白。

Java实用教程

2.1.3 注释语句
注释语句主要用来进行一些说明,或者标记一些无用的程 序语句。有两种注释方法,行注释为以//开始的行;块注释以/* 开始和*/结束,Java编译器忽略注释后的程序语句或说明。 例如,下面的语句就是注释语句用来说明程序文件名称的。
//程序文件名称为WelcomeApplet.java 上述的语句注释可以更改为: /*程序文件名称为WelcomeApplet.java*/ 或

/*
程序文件名称为 WelcomeApplet.java

*/

Java实用教程 2.1.4 标识符、关键字和转义符

在Java语言中,标识符是赋予变量、类和方法等的名称。
标识符由编程者自己指定,但需要遵循一定的语法规范:

(1) 标识符由字母、数字、下划线(_)、美元符号($)组成,
但美元符号用得较少。 (2) 标识符从一个字母、下划线或美元符号开始。 (3) Java语言中,标识符大小写敏感,必须区别对待。 (4) 标识符没有最大长度的限制,但最好表达特定的意思。 (5) 标识符定义不能是关键字。

Java实用教程 关键字又称保留字,是指Java语言中自带的用于标志数据 类型名或者程序构造名等的标识符,如public、double等。 转义符是指一些有特殊含义的、很难用一般方式表达的字 符,如回车、换行等。所有的转义符以反斜线(\)开头,后面跟 着一个字符来表示某个特定的转义符,如表2.1所示。

Java实用教程 表2.1 转 义 符

引 用 方 法 \b \t \n \f \r \' \" \\

含 退格 水平制表符 Tab 换行 表格符 回车 单引号 双引号 反斜线



Java实用教程

2.2 数据类型、变量和常量
2.2.1 数据类型 Java编程语言定义了八种基本的数据类型(见表2.2),共分为 四类:整数类(byte、short、int、long)、文本类(char)、浮点类 (double、float)和逻辑类(boolean)。

Java实用教程

表2.2 Java的数据类型
分 类 数据类型 字节型 短整型 整型 长整型 字符型 浮点型 双精度型 逻辑型 关键字 byte short int long char float double boolean 占字节数 8 16 32 64 16 32 64 8 缺省数值 0 0 0 0 ′\u 0000′ 0.0F 0.0D False 取 值 范 围 -2 ~2 7-1 -2 15~2 15-1 -2 31~2 31-1 -2 63~2 63-1 ′\u 0000′ ~ ′\u FFFF′ — —
7

整数类 文本类 浮点类 逻辑类

True、False

Java实用教程 1. 整数类 (1) 采用三种进制——十进制、八进制和十六进制。

2 —— 十进制值是2;
077 —— 首位的0表示这是一个八进制的数值;

0xBAAC —— 首位的0x表示这是一个十六进制的数值。
(2) 具有缺省int。

(3) 用字母“L”和“l”定义long。
(4) 所有Java编程语言中的整数类型都是带符号的数字。

Java实用教程 2. 文本类 (1) 代表一个16 bit Unicode字符。

(2) 必须包含用单引号(' ')引用的文字。
(3) 使用下列符号:

'a'——一个字符。
'\t'--一个制表符。 '\u???? '--一个特殊的Unicode字符,????应严格使用四个十 六进制数进行替换。

Java实用教程 3. 浮点类 默认为double类型,如果一个数字包括小数点或指数部分, 或者在数字后带有字母F或f(float)、D或d(double),则该数字为 浮点数。

Java实用教程 4. 逻辑类 boolean数据类型有两种值:true和false。 例如:boolean flag = true; 上述语句声明变量flag为boolean 类型,它被赋予的值为true。

Java实用教程 2.2.2 变量与常量 常量是指整个运行过程中不再发生变化的量,例如数学中 的π= 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.java

public class SetVariable
{ //全局变量

Java实用教程 static double pi = 3.141592654;//数学常量 static short s1; static int i1; static long l1;

static char ch1;
static float f1; static double d1; static boolean b1; public static void main(String args[])

{

Java实用教程

//局部变量
short s2 = 35; int i2 = -32; long l2 = 34555L; char ch2 = 'A';

float f2 = 897.89F;
double d2 = 34.345; boolean b2 = false; //输出常量 System.out.println("数学常量pi = " + pi); //输出局部变量

Java实用教程 System.out.println("******局部变量******"); System.out.println("短整型变量s2 = " + s2);

System.out.println("整型变量i2 = " + i2);
System.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实用教程

//方法:修改全局变量的值
public static void change() { 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.java

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

{
//变量初始化 int a = 30;

int b = 20;
//定义结果变量 int r1,r2,r3,r4,r5,r6,r7,r8,r9; //计算结果 r1 = a + b;

Java实用教程 r2 = a-b; r3 = a * b; r4 = a / b; 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("a*b = " + 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.java public class TestRelation { public static void main(String args[]) { //变量初始化 int a = 30; int b = 20; //定义结果变量 boolean r1,r2,r3,r4,r5,r6; //计算结果

Java实用教程 r1 = a == b; r2 = a != b; r3 = a > b; r4 = a < b; r5 = a >= b; r6 = a <= b; //输出结果 System.out.println("a = " + a + " b = " + b); System.out.println("a==b = " + r1); System.out.println("a!=b = " + r2); System.out.println("a>b = " + r3); System.out.println("a<b = " + r4); System.out.println("a>=b = " + r5); System.out.println("a<=b = " + r6); } }

Java实用教程

图2.4 程序输出结果

Java实用教程

2.3.3 布尔逻辑运算符
表2.3 布尔运算符及规则
运算符 ! & | ^ && || 含 义 取反 非简洁与 非简洁或 异或 简洁与 简洁或 !a a&b a|b a ^b a && b a || b 示 例 规 则

a 为真时,结果为假;a 为假时,结果为真 a、b 都为真时,结果为真;a、b 有一个为假时,结果为假 a、b 有一个为真时,结果为真;a、b 都为假时,结果为假 a、b 不同真假时结果为真;a、b 同真或同假时,结果为假 a、b 都为真时,结果为真;a、b 有一个为假时,结果为假 a、b 有一个为真时,结果为真;a、b 都为假时,结果为假

Java实用教程 图2.3为布尔逻辑运算符及其规则示例等。其中简洁与和简 洁或的执行结果分别与非简洁与和非简洁或的执行结果是一致 的,不同在于简洁与检测出符号左端的值为假时,不再判断符 号右端的值,直接将运算结果置为假;而简洁或与非简洁或的 不同在于简洁或检测出符号左端为真时,不再判断符号右端的 值,直接将运算结果置为真。 例如: Boolean a = false; Boolean b = true; a && b检测到a为假,则无需判断b的值,直接将值置为假; 而b || a时检测到b为真,则无需判断a的值,直接将值置为真。

Java实用教程

【例2.5】测试布尔表达式,程序输出结果如图2.5所示。源 程序代码如下:
//程序文件名称为TestLogic.java

public class TestLogic
{ public static void main(String args[]) { //变量初始化 boolean a = false; boolean b = true; //定义结果变量 boolean r1,r2,r3,r4,r5,r6; //计算结果

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

Java实用教程

图2.5 程序输出结果

Java实用教程

2.3.4 位运算符
Java中的常用位运算符如下: ~ 位求反

&
| ^ << >>

按位与
按位或 按位异或 左移 右移

>>>

不带符号右移

右移运算符对应的表达式为x>>a,运算的结果是操作数x被 2的a次方来除,左移运算符对应的表达式为x<<a,运算的结果 是操作数x乘以2的a次方。

Java实用教程

【例2.6】测试位运算符<<和>>,程序输出结果如图2.6所示。 源程序代码如下:
//程序文件名称为TestBit.java

public class TestBit
{ public static void main(String args[]) { //变量初始化

int a = 36;
int b = 2; //定义结果变量 int r1,r2;

Java实用教程 //计算结果 r1 = a >> b;

r2 = a << b;
//输出结果

System.out.println("a = " + a + " b = " + b);
System.out.println("a>>b = " + r1); System.out.println("a<<b = " + r2); } }

Java实用教程

图2.6 程序输出结果

Java实用教程 2.3.5 赋值运算符

赋值运算符分为简单运算符和复杂运算符。简单运算符指
“=”,而复杂运算符是指算术运算符、逻辑运算符、位运算符 中的双目运算符后面再加上“=”。表2.4列出Java常用的赋值运 算符及其等价表达式。

Java实用教程 表2.4 赋值运算符及其等价表达式
运算符 += 含 义 加并赋值运算符 减并赋值运算符 乘并赋值运算符 除并赋值运算符 取模并赋值运算符 与并赋值运算符 或并赋值运算符 或并赋值运算符 左移并赋值运算符 右移并赋值运算符 右移并赋值运算符 示 例 a += b a-= b a *= b a /= b a %= b a &= b a |= b a ^= b a <<= b a >>= b a >>>= b 等价表达式 a=a+b a = a -b a=a*b a=a/b a=a%b a=a&b a=a|b a =a ^b a = a << b a = a >> b a = a >>> b

-=
*= /= %= &= |= ^= <<= >>= >>>=

Java实用教程 2.3.6 其它操作符及其表达式

三目运算符(?:)相当于条件判断,表达式x?y:z用于判断x是
否为真,如果为真,表达式的值为y,否则表达式的值为z。 例如: int x = 5;

int a = (x>3)?5:3;
则a的值为5。如果x = 2,则a的值为3。

Java实用教程

对象运算符(instanceof)用来判断一个对象是否属于某个指
定的类或其子类的实例,如果是,返回真(true),否则返回假 (false)。 例如: boolean b = userObject instanceof Applet 用来判断userObject类是否是Applet类的实例。

Java实用教程 2.3.7 优先级 表2.5 运算符优先级
优先级 1 2 3 4 5 6 7 8 9 10 11 12 13 14 含义描述 分隔符 单目运算、字符串运算 算术乘除运算 算术加减运算 移位运算 大小关系运算、类运算 相等关系运算 按位与,非简洁与 按位异或运算 按位或,非简洁或 简洁与 简洁或 三目条件运算 简单、复杂赋值运算 [] () ; , ++ -- + * / % 运 算 ! 符 结合性 *右到左 左到右 左到右 左到右 左到右 左到右 左到右 左到右 左到右 左到右 左到右 *右到左 *右到左

-



(类型转换符)

+ << >> >>> < > <= >= instanceof == != & ^ | && || ?: = *= /= %= += - = &= ^= |=

<<=

>>=

>>>=

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.java
public class TestIf { //声明全局变量x static int x; public static void main(String args[]) { x = 12; if(x>10) {

Java实用教程 System.out.println("x = " + x + " 结果正确");

} else
System.out.println("x = 10" + " 结果不正确"); change(); System.out.println("修改x的值之后"); if(x>10) { System.out.println("x = " + x + " 结果正确"); } else System.out.println("x = 10" + " 结果不正确"); }

Java实用教程 //change方法:修改x的值 public static void change() { 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.java public class TestSwitch

{
public static void main(String args[]) //声明变量x int x; x = 12;

Java实用教程 System.out.println("x=12时打印的值"); choose(x); x = 3; System.out.println("x=3时打印的值"); choose(x);

}
//choose方法:switch语句结构 public static void choose(int x) { switch(x)

{

Java实用教程

case 1:
System.out.println(1); break;

case 2:
System.out.println(2); break; case 3: System.out.println(3); break; default: System.out.println(x); } }

}

Java实用教程

图2.8 程序输出结果

Java实用教程 2.4.2 for循环语句 for循环语句实现已知次数的循环,其基本格式为: for(初始化表达式;测试表达式;步长) { 语句或块; }

Java实用教程 其执行顺序如下: (1) 首先运行初始化表达式。 (2) 然后计算测试表达式,如果表达式为true,执行语句或 块;如果表达式为false,退出for循环。 (3) 最后执行步长。

Java实用教程 【例2.9】用for循环统计1~100(包括100)之间数的总和。程 序输出结果如图2.9所示。源程序代码如下:
//程序文件名称为TestFor.java public class TestFor { public static void main(String args[]) {

int sum = 0;
for(int i = 1; i<=100; i++) sum += i;

System.out.println("1到100(包括100)的数的总和为:" + sum);
} }

Java实用教程

图2.9 程序输出结果

Java实用教程 2.4.3 while循环语句 while循环语句实现受条件控制的循环,其基本格式为:

while(布尔表达式)
{

语句或块;
}

当布尔表达式为true时,执行语句或块,否则跳出while循
环。

Java实用教程 上面for循环语句的例子改为while语句后如下所示: int sum = 0;

int i = 1;
while (i<=100) { sum += i; i++;

}
System.out.println("1到100(包括100)的数的总和为:" + sum);

Java实用教程 2.4.4 do语句 do语句实现受条件控制的循环,其基本格式为: do { 语句或块; } while(布尔表达式)

Java实用教程 先执行语句或块,然后再判断布尔表达式。与while语句不 同,当布尔表达式一次都不为true时,while语句一开始判断就跳

出循环,不执行语句或块,而在do语句中则要执行一次。上面
那个例子改为do循环为: int sum = 0; int i = 1; do { sum += i; i++; } while (i<=100); System.out.println("1到100(包括100)的数的总和为:" + sum);

Java实用教程

2.5 数 组 的 使 用
2.5.1 数组声明 数组的定义如下: (1) 首先是一个对象。 (2) 存放相同的数据类型,可以是原始数据类型或类类型。 (3) 所有的数组下标默认从0开始,而且访问时不可超出定 义的上限,否则会产生越界错误。

Java实用教程

数组声明时实际是创建一个引用,通过代表引用的这个名
字来引用数组。数组声明格式如下: 数据类型 标识符[] 例如:

int a[];//声明一个数据类型为整型的数组a
pencil b[];//声明一个数据类型为pencil类的数组b

Java实用教程 2.5.2 创建数组 由于数组是一个对象,所以可以使用关键字new来创建一

个数组,例如:
a = new int[10];//创建存储10个整型数据的数组a b = new pencil[20];//创建存储20个pencil类数据的数组b 数组创建时,每个元素都按它所存放数据类型的缺省值被 初始化,如上面数组a的值被初始化为0,也可以进行显式初始 化。在Java编程语言中,为了保证系统的安全,所有的变量在 使用之前必须是初始化的,如果未初始化,编译时会提示出错。 有两种初始化数组的方式,分别如下:

Java实用教程 (1) 创建数组后,对每个元素进行赋值。 a[0]=5; a[1]=4; ... a[9] = 10; (2) 直接在声明的时候就说明其值,例如: int a[] = {4,5,1,3,4,20,2}; 说明了一个长度为7的一维数组。

Java实用教程 【例2.10】编写程序测试数组,程序输出结果如图2.10所示。 源程序代码如下: //程序文件名称为TestArray.java

public class TestArray
{ public static void main(String args[]) { //声明数组 int a[]; char b[];

//创建数组

Java实用教程 a = new int[3]; b = new char[2]; //数组初始化

for (int i = 0; i<3; i++)
{ a[i] = i*3;

}
b[0] = 'a'; b[1] = 'b'; //快速初始化数组 int c[] = {0,1*3,2*3}; //输出结果 System.out.print("数组a\n");

Java实用教程

for (int i = 0; i<2; i++)
{ System.out.print(b[i] + " "); } System.out.print("\n数组c\n");

for (int i = 0; i<3; i++)
{ System.out.print(c[i] + " ");

}
} }

Java实用教程

图2.10 程序输出结果

Java实用教程

习 题
1. 给出下列表达式的值。

(1) 3++4<<2^-8
(3) 36>>2*4&&48<<8/4+2

(2) "abc"&123||8<<2
(4) 2*4&&0<2||4%2

2. 编写程序,统计课程编号为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.java

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

{
apple a = new apple();//创建apple类 a.appleweight = 0.5;//实例变量赋值

System.out.println("苹果的重量为1两");
System.out.println(a.bite());//调用实例方法 a.appleweight = 5;

System.out.println("苹果的重量为5两");
System.out.println(a.bite()); } }

Java实用教程
//自定义类 class apple { //属性 long applecolor;//对应苹果的颜色 double appleweight;//苹果的重量 boolean eatup;//是否吃完 //类方法 public boolean bite() { if (appleweight<1) { System.out.println("苹果已经吃完了!哈哈"); eatup = true; }

Java实用教程
else { System.out.println("苹果吃不下了!:("); eatup = false; } return eatup;

}
}

Java实用教程

图3.1 自定义类的应用

Java实用教程 1. 类声明的基本格式 访问说明符 class 类名 extends 超类名 implements 接口名 其中: (1) 访问说明符为public或者缺省。public用来声明该类为公

有类,可以被别的对象访问。声明为公有的类存储的文件名为
类名。 (2) 类名:用户自定义的标识符,用来标志这个类的引用。 (3) 超类名:是指已经存在的类,可以是用户已经定义的, 也可以是系统类。 (4) 接口名:即后面讲到的接口。

Java实用教程 例如: public class HelloApplet extends Applet 访问说明符为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进行创建,例如:

HelloApplet hp = new HelloApplet();
例3.1中,自定义类apple,访问标识符缺省,定义三个属性:

long applecolor;//对应苹果的颜色
double appleweight;//苹果的重量

boolean eatup;//是否吃完

Java实用教程 一个方法为: public boolean bite()//类方法{...} 公有类SetApplet中引用自定义类,首先创建类的实例: apple a = new apple(); 其次赋初值: a.appleweight = 0.5;//实例变量赋值 最后调用它的方法: System.out.println(a.bite());//调用实例方法

Java实用教程

3.1.2 类的单继承性
Java编程语言中允许用extends关键字从一个类扩展出一个 新类,新类继承超类的成员变量和方法,并可以覆盖方法。

【例3.2】测试类的单继承性,程序输出结果如图3.2所示。 源程序代码如下:
//程序文件名TestExtend.java
public class TestExtend extends Employee { public static void main(String[] args) { System.out.println("覆盖的方法调用:" + getSalary("王一

",500));

Java实用教程
System.out.println("继承的方法调用:" + getSalary2("王一",500));

System.out.println("覆盖的方法调用:" + getSalary("王飞",10000));
System.out.println(“继承的方法调用:” + getSalary2(“王飞 ",10000));

}
public static String getSalary(String name, int salary) {

String str;
if (salary>5000) str = "名字: " + name + " Salary: " + salary; Salary: 低于5000";

else
str = "名字: " + name + "

Java实用教程
return str; } }; class Employee { public String name;//名字 public int salary;//薪水 public static String getSalary(String name, int salary) { String str; str = "名字: " + name + " return str; } Salary: " + salary;

Java实用教程
public static String getSalary2(String name, int salary) { String str; str = "名字: " + name + " return str; } Salary: " + salary;

};

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.java
public class UseSuper

{

Java实用教程 public static void main(String[] args) { Manager m = new Manager(); m.name = "王飞";

m.salary = 10000;
m.department = "业务部"; System.out.println(m.getSalary()); } } class Employee {

Java实用教程

public String name;//名字
public int salary;//薪水 //方法 public String getSalary() { String str; str = "名字: " + name + "\nSalary: " + salary; return str;

}
} class Manager extends Employee

Java实用教程 { public String department;//部门 //方法 public String getSalary() { //使用super变量调用超类的方法

return super.getSalary() + "\nDepartment: " + department;
} }

Java实用教程

图3.3 测试super变量的输出

Java实用教程

2. this
this变量指向当前对象或实例。 str = "名字: " + name + "\nSalary: " + salary; 上例中的语句可以换成下面的语句。 str = "名字: " + this.name + "\nSalary: " + this.salary; 这两者是等同的,因为在Java编程语言中,系统自动将this 关键字与当前对象的变量相关联。但有一种情况例外,就是当 在某些完全分离的类中调用一个方法并将当前对象的一个引用 作为参数传递时。例如: Day d = new Day(this);

Java实用教程

3.1.4 构造函数
类中的构造函数用来初始化一个类。构造函数为公有类型, 无返回值,用来从类实例中访问类时初始化此类的私有变量。 【例3.4】基于例3.3将公有变量改成私有变量之后,增加两 个构造函数,访问通过外部调用构造函数实现初始化赋值,得 到如图3.3所示的结果。 //程序文件名为UseConstruct.java public class UseConstruct

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

Java实用教程
Manager m = new Manager("王飞",10000,"业务部");//初始化赋值

System.out.println(m.getSalary());

} }

class Employee
{ private String name;//名字 private int salary;//薪水 //构造函数 public Employee(String _name, int _salary) {

Java实用教程 name = _name; salary = _salary; } public String getSalary() { String str; str = "名字: " + name + "\nSalary: " + salary; return str; } } class Manager extends Employee { private String department;

Java实用教程

//构造函数
public Manager(String _name, int _salary, String _department) { super(_name,_salary); department = _department; } public String getSalary() {

return super.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.java package Company;//声明包名Company class Employee

{
public String name;//名字

public int salary;//薪水
public String getSalary() {

Java实用教程 String str; str = "名字: " + name + "\nSalary: " + salary; return str; } } public class Manager extends Employee { public String department;//部门 public String getSalary() { return super.getSalary() + "\nDepartment: " + department; } }

Java实用教程 对此文件进行编译,生成类文件Manager.class。 在原目录建立源程序文件UsePackage.java。源程序代码如下:
//程序文件名UsePackage.java import Company.Manager;//引入包中的类 public class UsePackage { public static void main(String[] args) { Manager m = new Manager(); m.name = "王飞"; m.salary = 10000; m.department = "业务部"; System.out.println(m.getSalary()); } }

Java实用教程 编译后,在命令提示符状态下运行,输出结果如图3.4所 示。从图3.4中可以看出首先进入Company目录,编译

Manager.java文件,然后返回上层目录,编译UsePackage.java
文件,最后执行UsePackage类文件,输出正确的结果。

Java实用教程

图3.4 测试包的输出结果

Java实用教程

3.2 接 口
Java编程语言中禁止多继承属性,但可以通过接口来帮助类 扩展方法。接口中可以定义大量的常量和方法,但其中的方法 只是一种声明,没有具体的实现,使用接口的类自己实现这些 方法。接口与类的不同在于: (1) 没有变量的声明,但可以定义常量。 (2) 只有方法的声明,没有方法的实现。

接口声明的基本格式如下:
public interface 接口名 extends 接口列表

Java实用教程

【例3.6】测试接口,定义接口文件Product.java,定义了
两个常量,声明了一个方法。接口文件如下: //程序文件名Product.java public interface Product { static final String MAKER = "计算机制造厂"; static final String ADDRESS = "上海"; public int getPrice(); }

Java实用教程 使用接口的源文件代码如下:
//程序文件名UseInterface.java public class UseInterface { public static void main(String[] args) { Computer p = new Computer(); System.out.print(p.ADDRESS + p.MAKER); System.out.println(" 计算机的价格:" + p.getPrice()+ " 万元"); }

}

Java实用教程

class Computer implements Product
{ public int getPrice() { return 1;

}
}

Java实用教程

首先编译接口文件“javac Product.java”,然后编译使用这
个接口的类文件“javac.UseInterface.java”,最后执行类“java UseInterface”,输出结果如图3.5所示。

图3.5 测试接口的输出结果

Java实用教程

3.3 常用数据结构及类
3.3.1 Vector类

Vector类似于一个数组,但与数组相比在使用上有以下两个 优点。
(1) 使用的时候无需声明上限,随着元素的增加,Vector的 长度会自动增加。 (2) Vector提供额外的方法来增加、删除元素,比数组操作 高效。

Vector类有三个构造函数,分别如下:
public Vector(); 该方法创建一个空的Vector。

Java实用教程 public Vector(int initialCapacity); 该方法创建一个初始长度为initialCapacity的Vector。 public Vector(int initialCapacity, int capacityIncrement); 该方法创建一个初始长度为initialCapacity的Vector,当向 量需要增长时,增加capacityIncrement个元素。

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

Java实用教程 (2) Vector类中访问、修改对象的方法如下:

public Object get(int index)
返回index位置对象。 public Object set(int index, Object element) 修改index位置的对象为element。

Java实用教程

(3) 其它方法:
public String toString()

将元素转换成字符串。
public int size()

返回对象的长度。

Java实用教程

【例3.7】操作Vector对象,进行元素的添加、插入、修改和
删除。程序输出结果如图3.6所示。源程序代码如下: //程序文件名为UseVector.java import java.util.Vector;//引入JDK的Vector类

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

Java实用教程

Vector vScore = new Vector();
vScore.add(" 86"); //添加元素 vScore.add(" 98"); //添加元素 vScore.add(1, " 99"); //插入元素 //输出结果 for (int I = 0; I < vScore.size(); I++) { System.out.print(vScore.get(i) + " ");

}
vScore.set(1, " 77"); //修改第二个元素 vScore.remove(0); //删除第一个元素

Java实用教程 System.out.println(″\n修改并删除之后″);

for (int I = 0; I< vScore.size(); I++)
{ System.out.print(vScore.get(i) + " "); } System.out.println(" \n转换成字符串之后的输出\n" +

vScore.toString());
} };

Java实用教程

图3.6 操作Vector对象的输出结果

Java实用教程

3.3.2 Hashtable类
Hashtable类存储的是对象的名-值对。将对象的名和它的值 相关联同时存储,并可以根据对象名来提取它的值。在 Hashtable中,一个键名只能对应着一个键值,然而一个键值可 以对应多个键名,键名必须是惟一的。构造函数以及常用方法 如下:

public Hashtable()
构建散列表。

public Hashtable(int initialCapacity)
构建长度为initialCapacity的散列表。 public int size()

Java实用教程 返回散列表的名的个数。 public Object remove(Object key) 删除散列表中key名及其对应的value值。 public Object put(Object key,Object value) 将对象名key和对象值value存放到散列表中。 public Object get(Object key) 返回散列表key名对应的值。 public String toString() 转换成字符串。

Java实用教程

【例3.8】操作Hashtable对象,进行添加、修改、删除等操
作,输出结果如图3.7所示。源程序代码如下:
//程序文件名为UseHashtable.java import java.util.Hashtable;

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

{
Hashtable hScore = new Hashtable(); hScore.put("张一","86");

Java实用教程
hScore.put("李二","98"); hScore.put("海飞","99");

System.out.println("转换成字符串之后的输出:" + hScore.toString());

hScore.put("李二","77");
hScore.remove("张一");

System.out.println("修改并删除之后");

System.out.println("转换成字符串之后的输出:" + hScore.toString()); } }

Java实用教程

图3.7 操作Hashtable对象的输出结果

Java实用教程

3.3.3 Enumeration接口
实现Enumeration接口的对象生成一系列元素,通过 nextElement()方法依次读取下一个元素。只有以下两个方法:

public boolean hasMoreElements()
测试是否还有元素。 public Object nextElement() 返回枚举的下一个元素。 Enumeration接口及其方法通常与Vector、Hashtable一起连 用,用来枚举Vector中的项和Hashtable中的键名,例如: for (Enumeration e = v.elements() ; e.hasMoreElements() ;) System.out.println(e.nextElement());

Java实用教程 【例3.9】使用Enumeration接口枚举Vector中的对象和 Hashtable对象中的键名,并进行输出,结果如图3.8所示。源 程序代码如下:
//程序文件名UseEnumeration.java import java.util.*; public class UseEnumeration { public static void main(String[] args) { Vector vScore = new Vector(); vScore.add("86"); vScore.add("98");

Java实用教程
vScore.add(1,"99"); System.out.println("Vector:" + vScore.toString()); for (Enumeration e = vScore.elements() ; e.hasMoreElements() ;)

System.out.println(e.nextElement());
Hashtable hScore = new Hashtable();

hScore.put("张一","86");
hScore.put("李二","98"); hScore.put("海飞","99"); System.out.println("Hashtable:" + hScore.toString());

Java实用教程 for (Enumeration e = hScore.keys() ; e.hasMoreElements() ;) { String str = (String)e.nextElement();

System.out.print(str + ":");
System.out.println(hScore.get(str));

}
}

}

Java实用教程

图3.8 使用Enumeration接口枚举输出

Java实用教程 3.3.4 Date类 Date类用来指定日期和时间,其构造函数及常用方法如下: public Date() 从当前时间构造日期时间对象。 public String toString() 转换成字符串。 public long getTime() 返回自新世纪以来的毫秒数,可以用于时间计算。

Java实用教程 【例3.10】测试执行循环花费的时间(数量级为毫秒),具体 时间情况如图3.9所示。源程序代码如下: //程序文件名为UseDate.java
import java.util.Date; public class UseDate { public static void main(String[] args) {

Date dOld = new Date();
long lOld = dOld.getTime(); System.out.println("循环前系统时间为:" +dOld.toString());

Java实用教程
int sum = 0; for (int i=0; i<100; i++) { sum += i; } Date dNew = new Date(); long lNew = dNew.getTime(); System.out.println("循环后系统时间为:" +dNew.toString());

System.out.println("循环花费的毫秒数为:" + (lNew - lOld));
} }

Java实用教程

图3.9 循环时间测试

Java实用教程

3.3.5 String类
String类用于操作非数值型字符串,它提供了七类方法操 作,分别为字符串创建、字符串长度、字符串比较、字符串检 索、字符串截取、字符串运算和数据类型转换。 1. 字符串创建 public String() 构造一个空字符串。 public String(char[] value)

使用字符数组value中的字符以构造一个字符串。
public String(String original) 使用原字符串original的拷贝以构造一个新字符串。

Java实用教程

2. 字符串长度
public int length()

返回字符串的长度。
3. 字符串比较

public boolean equals(Object anObject)
比较字符串是否与anObject代表的字符串相同(区分大小写)。

public boolean equalsIgnoreCase(String anotherString)
比较字符串是否与anotherString相同(不区分大小写)。

Java实用教程 4. 字符串检索 public int indexOf(String str) 返回一个字符串中str第一次出现所在的位置。

public int indexOf(String str, int fromIndex)
返回从fromIndex开始字符串str出现所在的位置。

Java实用教程

5. 字符串截取
public String substring(int beginIndex, int endIndex)

返回benginIndex到endIndex之间的字符串。
6. 字符串运算

运算符为“+”,表示连接运算。下面的行语句输出连接的字符串。 System.out.println("Hashtable:" + hScore.toString());

Java实用教程

【例3.11】操作字符串,输出结果如图3.10所示。源程序 代码如下:
//程序文件名为TestString.java

public class TestString
{ public static void main(String[] args) { String str = new String("The substring begins at the specified beginIndex."); String str1 = new String("string"); String str2 = new String(); int size = str.length();//字符串长度

Java实用教程 int flag = str.indexOf("substring"); str2 = str.substring(flag,flag + 9);//取子字符串

System.out.println("字符串" + str + "\n总长度为:" + size);
if(str1.equals(str2))//判断是否相等 System.out.println("截取的字符串为:" + str1); else System.out.println("截取的字符串为:" + str2);

}
}

Java实用教程

图3.10 操作字符串的输出

Java实用教程

7. 数据类型转换
各种原始数据类型与String类型之间可以通过方法相互转换。 valueOf()系列的静态方法用于从其它对象(原始数据类型对 象)转换成字符串。例如: public static String valueOf(Boolean b)

public static String valueOf(char c)
public static String valueOf(int i)

public static String valueOf(long l)
public static String valueOf(float f) public static String valueOf(double d)

Java实用教程

具体实例如下:
(1) 从int转换到String。 例如: int intvar = 1; String strvar; strvar = String.valueOf (intvar); //"1"

Java实用教程 (2) 从float转换到String。 例如: float fltvar = 9.99f; String strvar;

strvar = String.valueOf(fltvar); //"9.99"

Java实用教程 (3) 从double转换到String。 例如:

double dblvar = 99999999.99;
String strvar;

strvar = String.valueOf (dblvar); //"9.999999999E7"

Java实用教程 (4) 从char转换到String。 例如: char chrvar = 'a'; String strvar; strvar = String.valueOf (chrvar); //"a"

Java实用教程 (5) 从String转换到int、float、long、double。 例如: String intstr = "10";

String fltstr = "10.1f";
String longstr = "99999999"; String dblstr = "99999999.9"; int i = Integer.parseInt(intstr); //10

float f = Float.parseFloat(fltstr); //10.1
long lo = Long.parseLong(longstr); //99999999 double d = Double.parseDouble(dblstr); //9.99999999E7

Java实用教程 (6) 从String转换到byte、short。 例如: String str = "0"; byte b = Byte.parseByte(str); //0

short sh = Short.parseShort(str);//0

Java实用教程 (7) 从String转换到char。 例如: String str = "abc";

char a = str.charAt(0);//返回字符a

Java实用教程 (8) 从String转换到boolean。 例如: String str = "true"; Boolean flag = Boolean.valueOf(str);//true

Java实用教程 3.3.6 StringBuffer类 StringBuffer类提供了一个字符串的可变序列,类似于String 类,但它对存储的字符序列可以任意修改,使用起来比String类

灵活得多。它常用的构造函数为:
StringBuffer()

构造一个空StringBuffer对象,初始容量为16个字符。
StringBuffer(String str) 构造一个StringBuffer对象,初始内容为字符串str的拷贝。 对于StringBuffer类,除了String类中常用的像长度、字 符串截取、字符串检索的方法可以使用之外,还有两个较为 方便的方法系列,即append方法系列和insert方法系列。

Java实用教程 (1) append方法系列根据参数的数据类型在StringBuffer对象 的末尾直接进行数据添加。 public StringBuffer append(boolean b) public StringBuffer append(char c) public StringBuffer append(char[] str) public StringBuffer append(char[] str, int offset, int len)

public StringBuffer append(double d)
public StringBuffer append(float f) public StringBuffer append(int i)

public StringBuffer append(long l)
public StringBuffer append(Object obj) public StringBuffer append(String str)

public StringBuffer append(StringBuffer sb)

Java实用教程 (2) insert方法系列根据参数的数据类型在StringBuffer的 offset位置进行数据插入。 public StringBuffer insert(int offset, boolean b)

public StringBuffer insert(int offset, char c)
public StringBuffer insert(int offset, char[] str) public StringBuffer insert(int index, char[] str, int offset, int len)

public StringBuffer insert(int offset, double d)
public StringBuffer insert(int offset, float f) public StringBuffer insert(int offset, int i) public StringBuffer insert(int offset, long l) public StringBuffer insert(int offset, Object obj)

public StringBuffer insert(int offset, String str)

Java实用教程 (3) 下面这个方法用于将stringbuffer对象的数据转换成字符串: public String toString()

Java实用教程 【例3.12】基于例3.11进行修改,使用StringBuffer对象得到 如图3.10所示的输出界面。
//程序文件名为TestString.java public class TestString { public static void main(String[] args) { StringBuffer str = new StringBuffer("The substring begins at the specified beginIndex.");

StringBuffer str1 = new StringBuffer("string");
String str2 = new String(); int size = str.length(); int flag = str.indexOf("substring");

Java实用教程
str2 = str.substring(flag,flag + 9); StringBuffer strOut = new StringBuffer("字符串"); strOut.append(str); strOut.append("总长度为:"); strOut.append(size); int f = strOut.indexOf("总"); strOut.insert(f,'\n'); System.out.println(strOut.toString()); if(str1.toString().equals(str2)) System.out.println("截取的字符串为:" + str1.toString()); else System.out.println("截取的字符串为:" + str2);
}

}

Java实用教程 3.3.7 StringTokenizer类 StringTokenizer类是一个实现Enumeration接口的类,它使 得应用程序可以将字符串分成多个记号,默认情况下以空格为 分隔符,例如将字符串“this is a test”分成四个单词记号。用户

也可以指定分隔符。分隔符为false,分割字符串;分隔符为
true,则将分隔符自身作为分割后的字符串的一部分。其构造 函数和常用方法如下: StringTokenizer(String str) 以字符串str构建StringTokenizer对象。

Java实用教程

StringTokenizer(String str, String delim)
使用delim分隔符,以初始字符串str构建StringTokenizer对象。 int countTokens() 返回识别的总记号数。 boolean hasMoreTokens() 测试是否还有识别的记号。 boolean nextToken(String delim)

返回字符串delim分隔的下一个记号。
String nextToken() 返回下一个识别的记号。

Java实用教程

【例3.13】使用StringTokenizer类分割字符串,字符串的分 割情况如图3.11所示。源程序代码如下:
import java.util.*;

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

String str = "数学::英语::语文::化学";
StringTokenizer st = new StringTokenizer(str,"::"); System.out.println(str + "\n课程数为:" +st.countTokens());

Java实用教程 while (st.hasMoreTokens()) { System.out.println(st.nextToken("::")); } str = "Hello this is a test"; st = new StringTokenizer(str); System.out.println(str + "\n单词数为:" +st.countTokens()); while (st.hasMoreTokens()) { System.out.println(st.nextToken()); } }

}

Java实用教程

图3.11 StringTokenizer分割单词的结果输出

Java实用教程

习 题
1. 定义一个类Student,属性为学号、姓名和成绩;方法为

增加记录SetRecord和得到记录GetRecord。SetRecord给出学号、
姓名和成绩的赋值,GetRecord通过学号得到考生的成绩。 2. 给出上题中设计类的构造函数,要求初始化一条记录(学 号、姓名、成绩)。 3. 假设一个学生所选课程为语文、数学、英语、政治、物 理、化学,给出此学生所选课程的Vector列表,并访问物理存放 在Vector中的位置。

Java实用教程 4. 对于图3.12中的Shebei表,将设备编码和设备名称作为 Hashtable中的键和值进行存储,然后访问此Hashtable,找到键 0008和0016并输出设备编码为0008、0016的设备名称。

图3.12 习题3.4中的Shebei表

Java实用教程 5. 编写程序,测试字符串“你好,欢迎来到Java世界”的 长度,将字符串的长度转换成字符串进行输出,并对其中的

“Java”四个字母进行截取,输出截取字母以及它在字符串中的
位置。 6. 对于图3.12中的Shebei表,将设备编码和设备名称用 :: 进行连接,形成新的字符串,存储到Vector向量对象中,如 0001::打印机、0008::书桌,然后访问Vector对象中设备编码为 0010、0014的项,使用字符串操作的方法读取这两项设备编码 对应的设备名称并输出。

Java实用教程 7. 编写程序,测试1~50的阶乘所耗费的毫秒级时间。 8. 编写程序,将设备编码对应设备名称的记录添加到一个 StringBuffer对象中,编码和名称之间用::隔开,每条记录之间 用**隔开。

9. 编写程序,将字符串“打印机*钟表//自行车**雨伞%%
收音机??电脑”进行拆分,输出每个设备的名字。

Java实用教程

第4章 Java Applet
4.1 Applet简介 4.2 显示Applet 4.3 载入图片 4.4 载入声音

4.5 Applet控制浏览器环境
4.6 服务器下配置Applet文件 4.7 使用插件载入Applet

4.8 JAR文件
4.9 Applet和应用程序 习 题

Java实用教程

4.1 Applet 简 介
4.1.1 Applet的定义 Applet是Java语言编写的,无法独立运行,但可以嵌入到 网页中执行。它扩展了传统的编程结构和方法,可以通过互联 网发布到任何具有Java编译环境浏览器的个体计算机上。

Java实用教程 4.1.2 Applet的用途 用户可以静态显示Applet,像显示一幅图片或者一段文本 一样;Applet也可以是一个动态交互过程,用户输入简单的数 据,就会产生相应的响应。

Java实用教程

4.1.3 Applet的编写格式
编写Applet时,首先要引入java.applet包中的类,这个类里 包含三个接口和Applet的类: import java.applet.*; import java.applet.Applet; 类头定义为: public class MyApplet extends Applet; 用来声明自定义类是从Applet类扩展而来的。

Java实用教程 类体中没有应用程序中必须具备的main方法,取而代之的 是下面几个常用方法: public void init();

初始化——在这个方法中设置一些变量的初始化,像界面 布局设置等。
public void start() 启动——Applet开始执行。 public void stop()

停止——Applet停止执行。
public void destroy() 撤消——销毁Applet。

Java实用教程 【例4.1】编写Applet,显示系统的当前时间。源程序代码如下: //程序文件名UseApplet.java

import java.awt.*;
import java.applet.Applet; import java.util.Date; public class UseApplet extends Applet {

String strTime = new String();
public void init() { }

Java实用教程

public void start()
{ Date d = new Date(); strTime = d.toString(); repaint();

}
public void paint(Graphics g) { g.drawString("当前时间为:" + strTime,20,30); } };

Java实用教程

4.2 显 示 Applet
4.2.1 工作流程 Applet是嵌入在HTML网页中显示的。首先从服务器请求 HTML网页,检测到Applet的类请求时,将所需类下载到本地, 然后运行,其工作流程如图4.1所示。
请求HTML页 载入HTML页

Internet 客户端 发现Applet标记请求类文件 载入类文件 服务器

图4.1 客户端显示Applet

Java实用教程

HTML页面中引用Applet的标签为<applet></applet>,浏览
器中执行Applet的步骤如下: (1) 浏览器请求HTML页面。 (2) 读HTML页面的过程中发现<applet>标签,然后继续向服

务器请求标签中声明的类文件。
(3) 浏览器获取该类文件。

(4) 字节码验证这个类是否合法。
(5) 如果合法就开始执行类文件。

Java实用教程

有时可能需要载入多个类文件,直到将所有所需的类文件
下载完毕为止。 为上面的UseApplet.class类写一个最简单的网页UseApplet.html: <html> <body> <applet code = "UseApplet.class" height = 200 width = 300> </applet> </body> </html>

Java实用教程

图4.2 Applet输出时间

Java实用教程

图4.3 网页下显示输出时间的Applet

Java实用教程 4.2.2 参数设置 在HTML页面中嵌入Applet类文件时,可以在<applet>标签

中设置属性以控制Applet类文件的外观显示,也可以传递一些
用户自定义属性。嵌入的格式为: <applet attributes1> <param attributes2>

...
</applet>

Java实用教程

其中:
(1) <applet></applet>标签内为Applet的信息。 (2) <param>标记在<applet></applet>之间进行设置,然后 由Applet自带的方法获取。 (3) <param>标记有两个自己的属性:name和value。例如: <param name ="aaa"value = "bbb"> (4) attribute1和attribute2的属性设置如表4.1所示。

Java实用教程 表4.1 属性设置及其描述
属性列表 放 置 属 性 code codebase height width vspace hspace align alt archive object name value 描 述 使用的 Applet 类文件的名字 基目录的 URL,Applet 的类文件都存放在这里 Applet 网页上占据的垂直像素高度 Applet 网页上占据的水平像素宽度 Applet 和其它 HTML 语句之间的垂直距离 Applet 和其它 HTML 语句之间的水平距离 与页中其余部分的对齐方式 不显示 Applet 时,显示的实际文本 浏览器预加载的其它文档资源的列表 代替 code 属性出现,将 Applet 类文件作为一个对象调用 Applet 程序中所需参数名 Applet 程序中所需参数传递的值

attribute1

<applet>

Attribute2

<PARAM>

Java实用教程 其中,code属性是必须的,height和width属性用来设置高 度和宽度,如果都为0,那么Applet将隐藏。 对于例4.1中UseApplet.html,如果有

<applet code = "UseApplet.class" height = 200 width = 300>
</applet> 那么说明网页加载的类名为UseApplet.class,类显示的高度为 200像素点,宽度为300像素点。 表4.1中列出的attibute1属性为<applet>定义的属性。用户 还可以根据Applet程序的需要,传递一些程序自身属性,这些 属性通过attribute2中name属性给出所需参数的名,value属性给 出所需参数的值。

public String getParameter(String name)

Java实用教程 【例4.2】基于例4.1,在加载类的网页上设置一个用户名, 使得Applet输出为“XXX,你好,当前时间为:(具体时间)”, 如图4.4所示。源程序代码如下:
//程序文件名UsePara.java import java.awt.*; import java.applet.Applet;

import java.util.Date;
public class UsePara extends Applet {

String strTime = new String();
String strUser = new String(); public void init() {

Java实用教程
//得到网页的参数:用户名 strUser = getParameter("USER");
} public void start() { Date d = new Date(); strTime = d.toString(); repaint(); } public void paint(Graphics g) { g.setColor(Color.red); g.drawString(strUser + " 你好,当前时间为:" + strTime,20,30); } };

Java实用教程

在UseApplet.html中添加一个用户参数设置:
<param name = "USER" value = 王飞>

使修改后的网页程序如下:
<html> <body> <applet code = "UsePara.class" height = 200 width = 400> <param name = "USER" value = 王飞>

</applet>
</body>

</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.6 Applet的生命周期

Java实用教程

4.3 载 入 图 片
在java.applet包中存在一个接口AppletStub。当一个Applet创 建之后,一个Applet Stub使用setStub方法附加到Applet上,这个 Stub用来充当Applet和浏览器环境之间的接口。在这个接口中一 个重要的方法: public URL getDocumentBase() 该方法返回的是Applet类文件所在网页的网络路径。 例如,如果一个Applet类文件嵌入在下面网页中


那么返回的路径为

Java实用教程 通过这个网络路径可以得到图片,从而由Applet类载入, 载入图片的方法为: public Image getImage(URL url, String name) 其中: (1) url给出图片所在的网路路径。 (2) name给出图片的名字。

例如:url路径可以为,
而name可以为路径下的图片index_01.gif。

Java实用教程 【例4.3】编写Applet,载入Applet类文件所在路径下的图片 index_01.gif,然后如图4.7所示显示图片。源程序代码如下: //程序文件名UseImage.java

import java.awt.*;
import java.applet.Applet; import java.net.*;

public class UseImage extends Applet
{ //定义图像对象 Image testImage; public void init()

{

Java实用教程
//得到图片 testImage = getImage(getDocumentBase(),"index_01.gif");

} public void paint(Graphics g) { g.drawImage(testImage,0,0,this); }
} 载入UseImage.class类的UseImage.html文件如下: <html> <body> <applet code = "UseImage.class" height = 200 width = 300> </applet> </body> </html>

Java实用教程

图4.7 Applet载入图片显示

Java实用教程

4.4 载 入 声 音
Applet类提供一个用于载入声音的方法,即 public AudioClip getAudioClip(URL url, String name) 该方法返回由url和name决定的AudioClip对象。 其中: (1) url:音频剪辑的绝对URL地址; (2) name:相对于上面的url,为音频剪辑的相对地址,通 常指名字。

Java实用教程 【例4.4】编写载入声音的Applet。源程序代码如下:
//程序文件名UseAudio.java import java.awt.*;

import java.applet.Applet;
public class UseAudio extends Applet {

public void init()
{ }

public void start()
{ //播放Applet所在目录下的tiger.au声音文件

getAudioClip(getDocumentBase(),"tiger.au").play();

Java实用教程 } }; 载入类的HTML文件如下: <html> <body>

<applet code = "UseAudio.class" height = 200 width = 300>
</applet </body> </html> 在浏览器加载或者appletviewer命令启动时可以听见老虎的 叫声,但必须保证tiger.au在UseAudio.class类文件所在的目录。

Java实用教程

4.5 Applet控制浏览器环境
java.applet包中提供一个接口AppletContext,对应着Applet 的环境,主要指包含Applet的网页文档等,在这个接口内有两 个重要方法: pubilc void showDocument(URL url)

浏览器下载Applet时,showDocument可以将当前Applet页
面用于显示url网址的内容。 url 给出页面的绝对网络路径。 public void showDocument(URL url, String target) target可以表明url显示的位置,有四种情况,如表4.2所示。

Java实用教程 表4.2 target 取 值
target 选项 _self _parent _top _blank 描 将 url 表示的页面显示在 Applet 框架中 将 url 表示的页面显示在父框架中,如果不存在,情况如同_self 将 url 表示的页面显示在 Applet 窗口的顶层框架,如果不存在,情况如同_self 将 url 表示的页面显示在新窗口中 述

public void showStatus(String status)

字符串status显示在状态栏中,告知用户当前类文件运行中的状态。

Java实用教程

【例4.5】编写Applet,在状态栏显示鼠标单击Applet的次数, 结果如图4.8所示。源程序代码如下:
//程序文件名ShowStatus.java import java.applet.*; import java.applet.Applet;

import java.awt.event.*;
public class ShowStatus extends Applet

{
int count = 0; public void init()

Java实用教程 { } public boolean mouseClicked(MouseEvent e) {

count ++;
getAppletContext().showStatus("你好,你已经点击 了" + count + "次了!"); return true; } };

Java实用教程

图4.8 状态栏显示单击次数信息

Java实用教程 【例4.6】编写Applet,在一个框架中显示不同来源的网页 信息,如图4.9所示。左框架为西安交通大学首页,右框架为新 浪网首页。源程序代码如下:
//程序文件名ShowHtml.java import java.applet.*; import java.applet.Applet; import java.net.URL;

public class ShowHtml extends Applet

{
public void init() { }

Java实用教程
public void start() { try

{
//创建URL对象 URL urlName=new URL("");

//在左框架显示网页
getAppletContext().showDocument(urlName,"left"); urlName = new URL(""); //右框架显示网页 getAppletContext().showDocument(urlName,"right"); }

Java实用教程
catch(MalformedURLException e)
{ System.out.println(e.getMessage()); } } } 载入Applet的网页Head.html的代码如下: <html>

<body>
<applet code = "ShowHtml.class" height = 0 width = 0> </applet>

Java实用教程
<h3>这是一个框架网页,上面的框架隐藏载入applet类文件,由
applet控制左框架显示西安交通大学的主页,右框架显示新浪网的主 页。

</body>
</html>

装配的框架网页ShowHtml.html的源代码如下,可以看见其中框架名
字左边的为left而右边的为right。 <html> <frameset rows="21%,*">

Java实用教程
<frame name="guid" src="Head.html">

<frameset cols="50%,*" frameborder="YES" border="1"
framespacing="1"> <frame name="left" src=""> <frame name="right" src=""> </frameset>

</frameset>
</html>

Java实用教程

图4.9 框架网页显示

Java实用教程

4.6 服务器下配置Applet文件
由于Applet文件是客户端浏览器从服务器端下载的HTML网 页,所以将文件配置到服务器端,由客户进行访问。

本机中使用的服务器为Tomcat 4.0,安装成功后重启动,则
服务器开始运转,在浏览器的网址栏键入

:8080/index.html,如果出现如图4.10所示的
Tomcat主网页,则证明服务器测试正常。

Java实用教程

图4.10 Tomcat主页

Java实用教程 配置自己的文件时,推荐在安装目录D:\Apache Tomcat 4.0\webapps\ROOT下建立自己的文件夹,这样有利于管理。本

书作者在此文件夹下建立user目录,以为载入图片的Applet为例,
将UseImage.html、UseImage.class和Image_01.gif拷贝到user目录 下,并在IE浏览器的地址栏键入网址: :8080/user/UseImage.html,浏览器显示结果 如图4.11所示,与前面例4.3中图4.7载入的图片效果一致,但可

以看出地址栏的网址不同。

Java实用教程

图4.11 配置到服务器端的网页显示

Java实用教程

4.7 使用插件载入Applet
Java插件(Plug-in)扩展了网络浏览器的功能,使得无论在哪 个浏览器(IE浏览器或者Netscape浏览器)下,Java Applet可在Sun 的Java运行环境(JRE)下运行,而不是在浏览器自带的JRE环境下 运行。Java插件是Sun的JRE环境的一部分,当安装JRE时,插件

自动安装。当你安装J2sdk-1.4.0_01时,JRE环境版本号也为
1.4.0_01。使用插件最大的不同是将IE浏览器中网页原有的 <applet>标签改成了<object>标签,在Netscape中则改成<embed>,

这里只讨论IE浏览器中的使用。

Java实用教程 J2sdk1.4提供了一个叫做HtmlConverter的工具,用于将包含 普通<applet>标签的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文件内容转换为:

<html>
<body> <!--"CONVERTED_APPLET"--> <!-- HTML CONVERTER --> <OBJECT

Java实用教程
classid="clsid:CAFEEFAC-0014-0000-0001-ABCDEFFEDCBA"
WIDTH = 300 HEIGHT = 200

codebase="#Version=1,4,0,10"> <PARAM NAME = CODE VALUE = "UseImage.class" > <PARAM NAME = ARCHIVE VALUE = "UseImage.jar" > <PARAM NAME="type" VALUE="application/x-java-applet;jpi-

version=1.4.0_01">

Java实用教程
<PARAM NAME="scriptable" VALUE="false">
</OBJECT> <!-<APPLET CODE = "UseImage.class" ARCHIVE = "UseImage.jar" WIDTH = 300 HEIGHT = 200> </APPLET> -->

<!--"END_CONVERTED_APPLET"-->
</body> </html>

Java实用教程 图 4 12

. HtmlConverter

工 具 界 面

Java实用教程 其中codebase="#Version=1,4, 0, 10">表示如果客户端浏览器 不存在此插件,可以从codebase指定的网址下载,由上述语句 行可以看出HtmlConverter生成的插件文件的插件下载地址为 Sun公司的网站。如果本机上放置了插件的安装程序,那么此 处可以改为从本机下载,以加快下载速度。如果在网站上发布 你的Applet的网页,建议使用插件方式载入Applet,可以与多 种浏览器兼容。

Java实用教程

4.8 JAR 文 件
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”的存档文件 中: jar cvf classes.jar Foo.class Bar.class ② 用一个存在的清单(manifest)文件“mymanifest”将foo/目录 下的所有文件存档到一个名为“classes.jar”的存档文件中: jar cvfm classes.jar mymanifest -C foo/ . 对JAR文件常用的操作有三种:创建JAR文件、列出JAR文 件和抽取JAR文件。

Java实用教程 1. 创建JAR文件 jar cvf UseImage.jar UseImage.class index_01.gif 当用JAR工具创建新的档案时,自动增加一个声明文件到 文档中。如果用户需要创建自己的声明文件时,则指定m选项。 可以看到本目录下多了一个UseImage.jar文件。创建JAR文件的

过程如图4.13所示。

图4.13 创建JAR文件

Java实用教程 2. 列出JAR文件的内容 jar tvf UseImage.jar 执行命令后列出JAR文件中的内容,如图4.14所示。

图4.14 列出JAR文件

Java实用教程 3. 抽取JAR文件 jar xvf UseImage.jar

抽取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文件
<applet>标签中添加一个属性名字为archive,它的值为要载 入的.jar文件。例如archive="UseImage.jar"。

例如,将D:\Apache Tomcat 4.0\webapps\ROOT\user\UseImage.html文件代码改为:
<html> <body> <applet code = "UseImage.class" archive="UseImage.jar" height = 200 width = 300> </applet> </body>

</html>

Java实用教程

4.9 Applet和应用程序
【例4.7】修改例4.1的Applet,使得它可以从命令提示符状 态下访问。 (1) 基于例4.1的UseApplet添加一个main方法如下: public static void main(String[] args)

{
//创建一个框架 Frame f = new Frame("时间"); //关闭窗口时退出系统 f.addWindowListener(new WindowAdapter()

{

Java实用教程 public void windowClosing(WindowEvent evt) {

System.exit(0);
} }); //创建一个AppletApp对象 AppletApp a = new AppletApp();

//将对象载入框架
f.add("Center",a); //设置框架大小

f.setSize(300,200);
//显示框架

Java实用教程

f.show();
//初始化对象

a.init();
//启动对象 a.start(); }

Java实用教程

(2) 修改后的源程序代码如下:
//程序文件名AppletApp.java import java.awt.*;

import java.awt.event.*;
import java.applet.Applet; import java.util.Date; public class AppletApp extends Applet { String strTime = new String(); public void init() { }

Java实用教程 public void start() {

Date d = new Date();
strTime = d.toString(); repaint(); } public void paint(Graphics g) { g.drawString("当前时间为:" + strTime,20,30); }

public static void main(String[] args)
{

Java实用教程

//创建一个框架
Frame f = new Frame("时间"); //关闭窗口时退出系统

f.addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent evt) { System.exit(0); } }); //创建一个AppletApp对象 AppletApp a = new AppletApp();

Java实用教程 a.init(); //将对象载入框架 f.add("Center",a);

f.setSize(200,400);
f.show(); a.start(); } };

Java实用教程 (3) 编译通过并生成UseApplet.class类后,在命令提示符状 态下键入“java UseApplet”,得到如图4.2所示的时间输出界面。

Java实用教程 【例4.8】修改例4.2,在命令提示符状态下输入用户名参数, 使得可以在命令提示符状态下进行访问。 (1) 从命令行状态输入用户名参数,应用程序的读取如下: if (args.length < 1) {

System.out.println("缺少用户参数");
System.exit(0);

}
else strUser = new String(args[0]);

Java实用教程 (2) 添加一个变量 static boolean inApplet = true; 用于控制取参数的方式,如果以应用程序调用,则从命令 行取参数;如果是载入Applet,则从网页中取参数。

Java实用教程 (3) 源程序代码如下: //程序文件名AppPara.java

import java.awt.*; import java.awt.event.*; import java.applet.Applet; import java.util.Date; public class AppPara extends Applet { String strTime = new String(); static String strUser = new String(); static boolean inApplet = true; public void init() {

Java实用教程 //如果从Applet载入,从网页得到参数 if(inApplet) strUser = getParameter("USER");

}
public void start() {

Date d = new Date();
strTime = d.toString(); repaint(); } public void paint(Graphics g) {

Java实用教程 g.setColor(Color.red); } public static void main(String[] args) { inApplet = false; //如果从命令行提示符状态进入,获取参数 if (args.length < 1) { System.out.println("缺少用户参数"); System.exit(0); } else

g.drawString(strUser + " 你好,当前时间为:" + strTime,20,30);

Java实用教程 strUser = new String(args[0]); //创建一个框架 Frame f = new Frame("时间"); //关闭窗口时退出系统 f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); //创建一个AppletApp对象 AppPara a = new AppPara();

Java实用教程

//初始化
a.init(); //将对象载入框架

f.add("Center",a);
//设置框架大小 f.setSize(400,200); //显示框架 f.show(); //启动对象 a.start(); } }

Java实用教程 (4) 在命令提示符状态键入命令“java AppPara 王飞”后 按回车键,弹出如图4.5所示的界面。

Java实用教程

习 题
1. 编写Applet,载入图片的同时响起音乐。 2. 将上题的Applet类、图片文件、音乐文件进行压缩并生成 JAR文件,然后载入运行。

Java实用教程

3. 编写程序,既可用作Applet,又可用作应用程序,在出
现的界面中显示下面的内容,括号内表示显示的颜色。 特点:(蓝色显示) (1) 跨平台性(以下均为红色显示) (2) 面向对象 (3) 安全性

(4) 多线程
(5) 简单易用

Java实用教程 4. 在上题的基础上,输入参数“Java语言”,使得显示内 容如下所示,要求既可以从命令行输入,也可以从网页内输入。 Java语言特点: (1) 跨平台性 (2) 面向对象 (3) 安全性

(4) 多线程
(5) 简单易用

Java实用教程

第5章 Java图形处理
5.1 Java图形 5.2 Paint方法、Update方法和Repaint方法 5.3 Graphics类

5.4 Color类
5.5 Graphics2D类 习 题

Java实用教程

5.1 Java图形
抽象窗口化工具(AWT)为图形用户界面编程提供API编程接

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

Java实用教程

5.2 Paint方法、Update方法和Repaint方法
1. Paint方法 public void paint(Graphics g) 以画布为参数,在画布上执行画图方法。在Applet中,不显 式地调用paint方法。

2. Repaint方法
Applet重画时系统自动调用paint方法。 3. Update方法 public void update(Graphics g) 更新容器,向Repaint发出刷新小应用程序的信号,缺省的 Update方法清除Applet画图区并调用Paint方法。

Java实用教程

5.3 Graphics类
Graphics类是所有图形上下文的抽象基类,允许应用程序在 各种设备上实现组件的画图。图形对象封装了Java支持的基本渲 染操作的状态信息,包括画图的组件对象、渲染区域的坐标 (coordinates)、区域(clip)、颜色(color)、字体(font)、画图模式等。

Graphics类提供画各种图形的方法,其中包括线、圆和椭圆、矩
形和多边形、图像以及各种字体的文本等。这些方法具体如下: public abstract void clipRect(int x, int y, int width, int height) 指定的区域切分。

Java实用教程

public abstract void drawLine(int x1, int y1, int x2, int y2)
使用当前颜色,在点(x1, y1) 和 (x2, y2) 之间画线。 public abstract void drawOval(int x, int y, int width, int height) 画椭圆。 public abstract void fillOval(int x, int y, int width, int height) 画实心椭圆。 public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) 画x和y坐标定义的多边形。

Java实用教程 public void drawRect(int x, int y, int width, int height) 画矩形。 public void drawRect(int x, int y, int width, int height) 画实心矩形。 public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 使用当前颜色画圆角矩形。 public abstract void drawString(String str, int x, int y) 使用当前字体和颜色画字符串str。

Java实用教程 public abstract void setColor(Color c)

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

Java实用教程

通过指定的name、style和size创建字体实例。name指字体
名,像“隶书”、“TimesRoman”等,字体风格为粗体、斜体, size指字号大小。 例如: Font f = new Font("TimesRoman",Font.BOLD + Font.ITALIC, 12); 创建了具有粗斜体风格的12磅的TimesRoman字体。

Java实用教程 【例5.1】设置Graphics对象画图,显示结果如图5.1所示。源 程序代码如下: //程序文件名SimpleGUI.java

import java.awt.*;
import java.applet.*; public class SimpleGUI extends Applet { Image samImage;

public void init()
{ samImage=getImage(getDocumentBase(),"sample.gif");

Java实用教程 } public void paint(Graphics g) { //g.clipRect(50,50,180,180); //画线

g.drawLine(0,0,20,30);
//输出字符串 g.drawString("图形显示",100,30);

//设置颜色
Color c = new Color(255,200,0); g.setColor(c); //设置字体

Java实用教程 Font f = new Font("TimesRoman",Font.BOLD+ Font.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实用教程 //多边形 int xC[] = {242,260,254,297,242};

int yC[] = {240,243,290,300,270};
g.drawPolygon(xC,yC,5); //图片 g.drawImage(samImage,250,50,this); }

}

Java实用教程

图5.1 简单的图形界面

Java实用教程 将例5.1注释的程序语句 // g.clipRect(50,50,180,180); 的注释符号去掉,重新编译执行,可以看见如图5.2所示的结果。

图5.2 裁剪后的图形界面

Java实用教程

5.4 Color类
Color类是用来封装颜色的,在上面的例子中多次用到。使 用Color对象较为简单的方法是直接使用Color类提供的预定义的 颜色,像红色Color.red、橙色Color.orange等;也可以使用RGB

颜色模式进行定义。所谓RGB颜色模式是指使用三种基色:红、
绿、蓝,通过三种颜色的调整得出其它各种颜色,这三种基色 的值范围为0~255。例如Color c = new Color(255,200,0);定义橙 色。表5.1给出常用颜色的RGB值以及对应的类预定义参数。

Java实用教程 表5.1 常用颜色的RGB值以及对应的类预定义参数
颜色名 白色 浅灰色 灰色 深灰色 黑色 红色 粉红色 橙色 黄色 绿色 品红色 深蓝色 蓝色 预定义颜色值 Color.white Color.lightGray Color.gray Color.darkGray Color.black Color.red Color.pink Color.orange Color.yellow Color.green Color.magenta Color.cyan Color.blue 红色值 255 192 128 64 0 255 255 255 255 0 255 0 0 绿色值 255 192 128 64 0 0 175 200 255 255 0 255 0 蓝色值 255 192 128 64 0 0 175 0 0 0 255 255 255

Java实用教程 Color还有一个构造函数,它构造的Color对象用于是否透 明显示颜色。 public Color(int red, int green, int blue, int alpha) 其中:前三个分量即RGB颜色模式中的参数,第四个alpha 分量指透明的程度。当alpha分量为255时,表示完全不透明,

正常显示;当alpha分量为0时,表示完全透明,前三个分量不
起作用,而介于0~255之间的值可以制造出颜色不同的层次效 果。

Java实用教程

【例5.2】测试Color对象,界面如图5.3所示。源程序代码如下:
//程序文件名UseColor.java import java.awt.*; import java.applet.*; import java.awt.geom.*; public class UseColor extends Applet {

public void paint(Graphics oldg)
{ Graphics2D g = (Graphics2D)oldg;

Java实用教程

g.setColor(Color.blue);
g.fill(new Ellipse2D.Float(50,50,150,150)); g.setColor(new Color(255,0,0,0)); g.fill(new Ellipse2D.Float(50,50,140,140)); g.setColor(new Color(255,0,0,64)); g.fill(new Ellipse2D.Float(50,50,130,130)); g.setColor(new Color(255,0,0,128)); g.fill(new Ellipse2D.Float(50,50,110,110)); g.setColor(new Color(255,0,0,255)); g.fill(new Ellipse2D.Float(50,50,90,90)); g.setColor(new Color(255,200,0)); g.fill(new Ellipse2D.Float(50,50,70,70)); } }

Java实用教程

图5.3 颜色测试界面

Java实用教程

5.5 Graphics2D类
Graphics2D类继承于Graphics类,提供几何学、坐标变换、 颜色管理以及文本排列等的更高级控制。Graphics2D类是Java平 台上渲染二维图形、文字、以及图片的基础类,提供较好的对绘 制形状、填充形状、旋转形状、绘制文本、绘制图像以及定义颜 色的支持。

在AWT编程接口中,用户通过Paint方法接收Graphics对象作 为参数,若是使用Graphics2D类,就需要在Paint方法中进行强制 转换。 Public void paint(Graphics old)
{ Graphics2D new = (Graphics2D)old; }

Java实用教程 5.5.1 绘制形状 Graphics2D提供以下两个方法进行形状的绘制: public abstract void draw(Shape s) 根据Graphics2D的环境设置画出形状s,其中Shape接口包 含的类如表5.2所示。 public abstract void fill(Shape s) 画实心形状s。

Java实用教程 表5.2 Graphics2D绘制的图形类

类 Line2D Rectangle2D RoundRectangle2D Ellipse2D GeneralPath 线 矩形 圆角矩形 椭圆 几何路径





Java实用教程 其中GeneralPath是一般的几何路径,它的构造函数为: public GeneralPath()

构造一个空的对象。
常用的方法有四个,分别如下:

public void lineTo(float x, float y)
从当前坐标点到(x,y)坐标点画一条直线,将此点添加到路径上。

public void moveTo(float x, float y)
移动到坐标点(x,y),在路径上添加此点。

Java实用教程 public void quadTo(float x1, float y1, float x2, float y2) 以坐标点(x1,y1)为控制点,在当前坐标点和坐标点(x2, y2)之间插入二次曲线片断。 public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) 以(x1,y1)和(x2,y2)为控制点,在当前坐标点和(x3,y3)

之间插入曲线片断。

Java实用教程

在Draw方法中提到Graphics2D的环境设置。所谓的环境设
置是指设置画图的笔画和填充属性等,设置方法分别如下: public abstract void setStroke(Stroke s) 设置笔画的粗细。其中Stroke接口中常用BasicStroke类来实 现,一个较简单的构造函数为 public BasicStroke(float width) 创建实线笔画宽度为width。 public abstract void setPaint(Paint paint)

Java实用教程

设置Graphics2D环境的填充属性。其中,paint的值可以为渐
变填充类java.awt.GradientPaint,也可以为图形填充类

java.awt.TexturePaint,后者将在5.5.3节绘制图像中讲到。渐变填
充类常用构造函数为 public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2, boolean cyclic) 构建一个渐变GradientPaint对象,在起始坐标点到目标坐标 点之间从颜色color1到color2渐变,cyclic为真,循环渐变。

Java实用教程

【例5.3】演示了几何形状、笔画变换以及颜色渐变显示。 其中直线的笔画宽度为10,其它笔画宽度为5,中间三个图形实 现绿色到蓝色的循环渐变,后三个图形实现红色到黄色的循环 渐变,如图5.4所示。
//程序文件名GUI2D.java import java.awt.*; import java.applet.*; import java.awt.geom.*; public class GUI2D extends Applet {

Java实用教程 public void paint(Graphics oldg) { Graphics2D g = (Graphics2D)oldg;

//设置笔画宽度
BasicStroke stroke = new BasicStroke(10); g.setStroke(stroke); //画线 Line2D line = new Line2D.Float(0,0,20,30); g.draw(line); line = new Line2D.Float(50,50,100,50); g.draw(line);

Java实用教程

line = new Line2D.Float(50,50,50,100);
g.draw(line); stroke = new BasicStroke(5); g.setStroke(stroke); //设置渐变填充 GradientPaint gt = new GradientPaint(0,0,Color.green,50,30,Color.blue,true);

g.setPaint((Paint)gt);
//画矩形 Rectangle2D rect = new Rectangle2D.Float(80,80,40,40);

Java实用教程 g.draw(rect); rect = new Rectangle2D.Float(100,100,40,40); g.fill(rect); //画椭圆 Ellipse2D ellipse = new Ellipse2D.Float(120,120,30,40);

g.draw(ellipse);
gt = new GradientPaint(0,0,Color.red,30,30,Color.yellow,true); g.setPaint((Paint)gt); ellipse = new Ellipse2D.Float(140,140,20,20); g.fill(ellipse);

Java实用教程

//画圆角矩形 RoundRectangle2D roundRect = new RoundRectangle2D.Float(160,160,40,40,20,20); g.draw(roundRect); roundRect = new RoundRectangle2D.Float(180,180,40,40,20,20); g.fill(roundRect); //画几何图形 GeneralPath path = new GeneralPath(); path.moveTo(150,0); path.lineTo(160,50); path.curveTo(190,200,240,140,200,100); g.fill(path); } }

Java实用教程

图5.4 通过Graphics2D对象绘制形状

Java实用教程

5.5.2 绘制文本
Graphics2D类提供一个文本布局(TextLayout)对象,用于实 现各种字体或段落文本的绘制。其构造函数为: public TextLayout(String string, Font font, FontRenderContext frc) 通过字符串string和字体font构造布局。

public void draw(Graphics2D g2, float x, float y)
将这个TextLayout对象画到Graphics2D对象g2上的x,y坐标 处。 public Rectangle2D getBounds() 返回TextLayout对象的区域。

Java实用教程 【例5.4】测试绘制文本功能,如图5.5所示。源程序代码如下: //程序文件GUIText.java

import java.awt.*;
import java.applet.*; import java.awt.geom.*; import java.awt.font.*; public class GUIText extends Applet { public void paint(Graphics oldg) {

Java实用教程 Graphics2D g = (Graphics2D)oldg; //设置字体 Font f1 = new Font("Courier",Font.PLAIN,24); Font f2 = new Font("helvetica",Font.BOLD,24); FontRenderContext frc = g.getFontRenderContext();

String str = new String("这是一个文本布局类的实现");
String str2 = new String("扩充绘制文本的功能"); //构造文本布局对象 TextLayout layout = new TextLayout(str, f1, frc); Point2D loc = new Point2D.Float(20,50);

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

Java实用教程

图5.5 Graphics2D对象绘制文本

Java实用教程 5.5.3 绘制图像 绘制图像用到BufferedImage类,BufferedImage类是指存放 图像数据的可访问的缓冲。其构造函数为: public BufferedImage(int width, int height, int imageType)

使用宽度(width)、高度(height)和imageType类型构造
BufferedImage对象。

public Graphics2D createGraphics()

Java实用教程 用图片填充椭圆的具体过程如下: (1) 创建一个Graphics2D,可以画到BufferedImage中。

例如构建一个BufferedImage对象buf。
BufferedImage buf = new BufferedImage (img.getWidth(this), img.getHeight(this),BufferedImage.TYPE_INT_ARGB); 创建一个临时Graphics2D对象: Graphics tmpG = buf.createGraphics();

将图像画入临时缓冲:
tmpG.drawImage(img,10,10,this);

Java实用教程 (2) 用TexturePaint类进行填充: public TexturePaint(BufferedImage txtr, Rectangle2D anchor)

构造TexturePaint对象,需要一个Rectangle2D对象来存放该对象: Rectangle2D rect = new Rectangle2D.Float(0,0,h,w); TexturePaint t = new TexturePaint(buf,rect); (3) 然后设置填充模式,并进行填充: g.setPaint(t); g.fill(new Ellipse2D.Float(100,50,60,60));

Java实用教程

【例5.5】完成图像显示,并将区域蓝色透明显示,然后进
行图片填充,如图5.6所示。源程序代码如下: //程序文件名GUIImage.java import java.awt.*; import java.applet.*; import java.awt.geom.*; import java.awt.font.*; import java.awt.image.*; import java.net.*;

Java实用教程 public class GUIImage extends Applet { public void paint(Graphics oldg) {

Graphics2D g = (Graphics2D)oldg;
try {
URL imgURL = new URL(getDocumentBase(),"sample.gif");

Image img = getImage(imgURL); int h = img.getHeight(this); int w = img.getWidth(this);

Java实用教程

//构造缓冲图像对象
BufferedImage buf = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB); //放入临时图形类 Graphics tmpG = buf.createGraphics(); tmpG.drawImage(img,10,10,this); g.drawImage(buf,10,20,this); //设置透明颜色对象

Color transBlue = new Color(0,0,255,100);
g.setColor(transBlue); GeneralPath path = new GeneralPath();

Java实用教程 path.moveTo(60,0); path.lineTo(50,100); path.curveTo(160,230,240,140,200,100); g.fill(path);

transBlue = new Color(0,0,255,240);
g.fill(new Ellipse2D.Float(100,100,50,50));

Rectangle2D rect = new Rectangle2D.Float(0,0,h,w);
//图片填充 TexturePaint t = new TexturePaint(buf,rect);

Java实用教程 g.setPaint(t); g.fill(new Ellipse2D.Float(100,50,60,60)); } catch(Exception e) { System.out.println("Error:" + e.getMessage()); } }

}

Java实用教程

图5.6 通过Graphics2D对象绘制图像

Java实用教程

习 题
1. 使用Graphics类进行图形绘制,要求绘制深蓝色矩形和红

色椭圆形,然后分别进行填充。
2. 使用Graphics2D类绘制粉红色到蓝色的渐变,填充到圆

角矩形、多边形,笔画宽度为10。
3. 绘制文本“欢迎来到Java世界”,其中“欢迎来到”为

蓝色显示,而“Java世界”为橙色显示,文本用矩形框起来,
底色为黄色。 4. 画一个三角形区域,然后用图片进行填充。

Java实用教程

第6章 Java用户界面技术
6.1 用户界面对象
6.2 布局

6.3 java.swing包
习 题

Java实用教程

6.1 用户界面对象
用户界面上经常用到的组件对象有Button(按钮)、 Checkbox(复选框)、Choice(组合框)、Label(标签)、List(列表)、 Scrollbar(滚动条)、TextComponent(TextArea(文本区域)、 TextField(文本框))和Panel(面板)。这些组件类的继承情况如下: java.lang.Object

|
+--java.awt.BorderLayout +--java.awt.FlowLayout +--java.awt.Component

Java实用教程 | +--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.TextField

Java实用教程 6.1.1 按钮 Button类创建一个带标签的按钮对象,当按下一个按钮时, 可以引发一些事件,包含一系列的动作或操作。例如单击按钮, 使得界面颜色发生变化等。它的构造函数以及主要的方法如下: public Button()

构建一个没有标签的按钮。
public Button(String label) 构建一个显示为label的按钮。 public void setLabel(String label) 设置显示标签为字符串label。

public String getLabel()
获取按钮的标签,返回为字符串。

Java实用教程 【例6.1】测试Button类的Applet。用户界面如图6.1所示。 源程序代码如下: //程序文件名UseButton.java

import java.awt.*;
import java.applet.*; import java.applet.Applet; public class UseButton extends Applet { String str1 = new String(); //声明按钮对象 Button b1; Button b2;

Java实用教程

public void init()
{ //构造对象

b1 = new Button();
b2 = new Button("按钮对象2"); //添加到界面

this.add(b1);
this.add(b2); } public void start() {

Java实用教程 b1.setLabel("按钮对象1"); str1 = b2.getLabel();

repaint();
}

public void paint(Graphics g)
{ g.drawString(str1,20,30); } };

Java实用教程 启动Applet的HTML页面代码如下: <html> <body> <applet code = "UseButton.class" height = 200 width = 300> </applet>

</body>
</html>

Java实用教程

图6.1 测试Button类的界面

Java实用教程 6.1.2 复选框和单选按钮 复选框是一个图形组件,有两个状态,即“选中”(true)和

“未选中”(false)。单击复选框时可以在“选中”、“未选中”
之间进行切换。在Java编程语言中,单选按钮没有单独的类, 而是作为复选框的特例存在,用户通过把一组复选框放置在同

一个复选框组中创建一套单选按钮。它的构造函数和其它方法
如下: public Checkbox() 创建一个没有标签的复选框。 public Checkbox(String label)

创建一个标签为lable的复选框。

Java实用教程 public Checkbox(String label, boolean state) 创建一个标签为lable的复选框,并设置初始状态。 public CheckboxGroup() 创建一个复选框组,用来放置单选按钮。 public Checkbox(String label, CheckboxGroup group, boolean state) 创建一个标签为lable的复选框,添加到group组中并设置初 始状态,作为单选按钮的形式出现。

Java实用教程 public String getLabel() 获得复选框的标签。

public void setLabel(String label)
设置标签。

public boolean getState()
返回复选框所在的状态,是选中还是未选中。 public void setState(boolean state) 设置状态,用来初始化复选框的状态。

Java实用教程

【例6.2】测试复选框和单选按钮的用法,用户界面如图6.2
所示。源程序代码如下: //程序文件名UseCheckbox.java import java.awt.*; import java.applet.*;

import java.applet.Applet;
public class UseCheckbox extends Applet { String str1 = new String(); boolean b1 = false;

boolean b2 = false;

Java实用教程

Checkbox c1,c2,c3;
Checkbox cRadio1,cRadio2; CheckboxGroup c; public void init() {

c1 = new Checkbox();
c2 = new Checkbox("复选框对象2"); c3 = new Checkbox("复选框对象3",true); //构造单选按钮 c = new CheckboxGroup(); cRadio1 = new Checkbox("单选按钮1",c, false);

Java实用教程

cRadio2 = new Checkbox("单选按钮2",c,true);
//添加到界面 this.add(c1); this.add(c2); this.add(c3); this.add(cRadio1); this.add(cRadio2); }

public void start()
{ c1.setLabel("复选框对象1");

Java实用教程 str1 = c2.getLabel(); b1 = c3.getState(); b2 = cRadio1.getState(); repaint(); } public void paint(Graphics g) { g.drawString("获取第二个对象的标签:" + str1,40,80); g.drawString("复选框3的状态为:" + b1,40,100);

g.drawString("单选按钮1的状态为:" + b2, 40,120);
} };

Java实用教程

图6.2 复选框和单选按钮测试

Java实用教程 6.1.3 组合框 组合框代表一系列选择的弹出式菜单,当前选择显示为菜 单的标题。它的构造函数和其它常用方法如下: public Choice() 构建一个选择项菜单。

public void add(String item)
将item添加到选择菜单中。

public String getItem(int index)
返回选择菜单中index位置的项,注意索引是从0开始的, 而项数从1开始。

Java实用教程 public int getItemCount() 返回选择菜单总的项数。

public String getSelectedItem()
返回当前选中的项。 public int getSelectedIndex() 返回当前选中项的索引。 public void insert(String item, int index) 在index处插入字符串item。 public void remove(int position)

删除position位置的项。

Java实用教程

public void remove(String item)
删除item项。

public void removeAll()
删除所有的项。

public void select(int pos)
将pos处的项设为选中状态,通常用于初始化。

public void select(String str)
将str项设为选中状态,通常用于初始化。

Java实用教程

【例6.3】测试Choice类,用户界面如图6.3所示。源程序代码如下:
//程序文件名UseChoice.java import java.awt.*; import java.applet.*; import java.applet.Applet;

public class UseChoice extends Applet
{ String str1 = new String(); String str2 = new String(); int count = 0; int i1 = 0;

Java实用教程 boolean b1 = false; Choice c1;//声明组合框对象 public void init() { //初始化组合框对象, c1 = new Choice(); c1.add("语文"); c1.add("数学"); c1.add("物理"); c1.add("化学"); c1.add("生物"); c1.select(3); this.add(c1); }

Java实用教程 public void start() { count = c1.getItemCount(); str1 = c1.getItem(2); str2 = c1.getSelectedItem(); i1 = c1.getSelectedIndex(); repaint(); } public void paint(Graphics g) { g.drawString("元素总个数为:" + count,10,80); g.drawString("第2项元素为:" + str1,10,100); g.drawString("选中项的元素为:" + str2,10,120); g.drawString("选中项的位置为:" + i1,10,140); } };

Java实用教程

图6.3 测试Choice实例的用户界面

Java实用教程 在上例的基础上添加一个方法operate,并在start方法中调用此 方法,程序段如下: public void operate() { c1.insert("英语",3); c1.remove("生物"); } public void start() { operate(); count = c1.getItemCount(); ... }

Java实用教程

图6.4 修改操作后的用户界面

Java实用教程

6.1.4 标签
标签对象就是将文本放入一个容器内的组件,显示一行只

读文本。文本可以由程序修改,用户无法直接修改。它的构造
函数和其它常用方法如下: public Label() 构建一个空标签。 public Label(String text) 构建一个text内容的标签,默认为左对齐。 public Label(String text, int alignment)

Java实用教程 构建一个内容为text,以alignment方式对齐的标签,其中 alignment的取值如表6.1所示。

表6.1 标签alignment的属性取值

alignment 可选值 Label.LEFT Label.RIGHT Label.CENTER

对 应 数 值 0 2 1

对 齐 方 式 左对齐 右对齐 中间对齐

Java实用教程 public String getText() 获得标签文本。 public void setText(String text) 设置标签文本。 public int getAlignment()

获得标签文本对齐方式,返回为整型值。

Java实用教程

【例6.4】测试Label类,用户界面如图6.5所示。源程序代码如下: //程序文件名UseLabel.java

import java.awt.*;
import java.applet.*; import java.applet.Applet; public class UseLabel extends Applet {

String str1 = new String();
int i1 = 0; Label l1;//声明对象

Label l2;

Java实用教程

Label l3;
public void init() { l1 = new Label(); l2 = new Label("标签对象2"); l3 = new Label("标签对象3",Label.CENTER); this.add(l1); this.add(l2); this.add(l3); } public void start() {

Java实用教程 l1.setText("标签对象1"); str1 = l2.getText(); i1 = l3.getAlignment();

repaint();
} public void paint(Graphics g) { g.drawString("获取第二个对象的文本:" + str1,40,60); g.drawString("标签对象3的对齐方式为:" + i1,40,80); } };

Java实用教程

图6.5 Label对象的界面

Java实用教程 6.1.5 列表 List展示给用户一个滚动的文本项列表。用户可以选择其中 一项或多项。它的构造函数和其它常用方法如下: public List() 构建一个新的空滚动列表。

public List(int rows)
构建一个新的rows可见行的滚动列表。

public List(int rows, boolean multipleMode)
构建一个新的rows可见行的滚动列表,并设置是否可以多 项选择。multipleMode为true时,允许用户多项选择。

Java实用教程

public void add(String item)
在滚动列表最后添加新的一项item。 public void add(String item, int index) 在index位置添加item项。 public String getItem(int index) 返回index位置的项。 public int getItemCount()

返回列表中项的数目。
public String[] getItems() 返回列表中的项,为一个字符串数组。

Java实用教程 public int getSelectedIndex()

返回列表中选中项的索引。
public String getSelectedItem() 返回列表中选中的项。 public boolean isIndexSelected(int index) 判断index项是否选中。

public void remove(int position)
删除position项。 public void remove(String item) 删除item项。

Java实用教程 public void removeAll() 删除列表中所有元素。 public void replaceItem(String newValue, int index) 将index位置的项替换为newValue。 public void select(int index) 选中index位置的项,通常用于初始化。

Java实用教程

【例6.5】测试List类,用户界面如图6.6所示。源程序代码如下: //程序文件名UseList.java import java.awt.*; import java.applet.*;

import java.applet.Applet;
public class UseList extends Applet {

String str1 = new String();
String str2 = new String(); int i1 = 0; int i2 = 0;

Java实用教程 List l1,l2,l3;//声明对象 public void init() { l1 = new List(); l2 = new List(5); l3 = new List(5,true); //列表添加内容 l1.add("苹果"); l1.add("香蕉");

l1.add("梨");
l2.add("语文"); l2.add("数学");

Java实用教程 l2.add("英语"); l2.add("化学"); l3.add("钢笔"); l3.add("铅笔"); l1.select(1); l3.select(1); this.add(l1); this.add(l2); this.add(l3);

}
public void start() {

Java实用教程 str1 = l1.getItem(2); i1 = l1.getItemCount(); l2.replaceItem("英语",2); str2 = l3.getSelectedItem(); repaint();

} public void paint(Graphics g) { g.drawString("第一个对象的索引为2的元素:" + str1,40,100); g.drawString("第一个对象的元素个数:" + i1,40,120); g.drawString("第三个对象选中的元素为:" + str2,40,140); } };

Java实用教程

图6.6 List对象的界面

Java实用教程 6.1.6 滚动条 Scrollbar给用户提供一个组件,方便用户在一系列范围的

值中进行选择。它的常用属性如表6.2所示。
表6.2 Scrollbar类的常用属性及缺省值
属 性 Orientation(方向) Minimum(最小值) Maximum(最大值) Value(数值) Unit increment(单位移动) Block increment(块移动) 描 述 缺 省 值 Scrollbar.VERTICAL(1) 0 100 0 1 10

水平还是垂直 滚动条的最小值 滚动条的最大值 滚动条的值 单击滚动条两端箭头时移动的单位 单击滚动条空白处时移动的单位

Java实用教程 它的构造函数和其它常用方法如下: public Scrollbar() 构建一个新的垂直滚动条。 public Scrollbar(int orientation) 构建一个指定方向的滚动条。Orientation的值为 HORIZONTAL(0)表示水平滚动条,值为VERTICAL(1)表示垂直 滚动条。 public Scrollbar(int orientation, int value, int visible, int minimum, int maximum) 构建一个指定方向、初始值、可见性、最小值和最大值的滚动 条。

Java实用教程 public int getValue() 返回滚动条的当前值。 public int getMinimum() 返回最小值。 public int getMaximum() 返回最大值。

Java实用教程

【例6.6】测试Scrollbar类,用户界面如图6.7所示。源程序代码如下: //程序文件名UseScrollbar.java import java.awt.*; import java.applet.*; import java.applet.Applet; public class UseScrollbar extends Applet { int i1 = 0; int i2 = 0; int i3 = 0; int i4 = 0; int i5 = 0; Scrollbar s1;//声明对象

Java实用教程 Scrollbar s2; Scrollbar s3; public void init() { s1 = new Scrollbar(); s2 = new Scrollbar(Scrollbar.HORIZONTAL); s3 = new Scrollbar(Scrollbar.VERTICAL,50,0,10,500); this.add(s1); this.add(s2); this.add(s3); } public void start() {

Java实用教程 i1 = s1.getOrientation(); i2 = s2.getOrientation();

i3 = s3.getValue();
i4 = s3.getMinimum(); i5 = s3.getMaximum(); repaint(); }

public void paint(Graphics g)
{ g.drawString("第一个对象的方向:" + i1,40,80);

Java实用教程 g.drawString("第二个对象的方向:" + i2,40,100); g.drawString("第三个对象的滑块值:" + i3,40,120); g.drawString("第三个对象的最小值:" + i4,40,140); g.drawString("第三个对象的最大值:" + i5,40,160); } };

Java实用教程

图6.7 Scrollbar对象的测试界面

Java实用教程 6.1.7 文本框 TextField对象用作单行文本的编辑。它的构造函数和其它常用 方法如下: public TextField() 构建一个空的文本框。

public TextField(int columns)
构建一个文本框,columns给出文本框的宽度。

public TextField(String text)
构建一个文本框,用text给出初始化内容。 public TextField(String text, int columns)

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

返回文本框的内容,返回值为字符串。
public void setEditable(boolean b) 设定文本框内容是否是用户可编辑的,b为false时,表示不 可编辑,b为true时,表示可编辑。通常创建一个文本框时默认 为用户可编辑的。 public int getColumns() 获取列数。

Java实用教程 【例6.7】TextField类的测试,用户界面如图6.8所示。源程 序代码如下: //程序文件名UseTextField.java import java.awt.*; import java.applet.*; import java.applet.Applet; public class UseTextField extends Applet { String str1 = new String(); int i1 = 0; int i2 = 0; TextField tf1, tf2, tf3, tf4; public void init() {

Java实用教程

tf1 = new TextField();
tf2 = new TextField(20); tf3 = new TextField("文本对象3"); tf4 = new TextField("文本对象4", 30); add(tf1);

add(tf2);
add(tf3); add(tf4); } public void start() {

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

Java实用教程

图6.8 TextField对象的界面

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

Java实用教程 public TextArea(String text, int rows, int columns) 构建一个文本为text、行数为rows、列数为columns的文本区 域。 public TextArea(String text, int rows, int columns, int scrollbars)

构建一个文本为text、行数为rows、列数为columns的文本
区域。滚动条的情况由scrollbars参数决定。Scrollbars的取值如

表6.3所示。

Java实用教程

表6.3 TextArea中的滚动条属性值
参 数 SCROLLBARS_BOTH SCROLLBARS_VERTICAL_ONLY SCROLLBARS_HORIZONTAL_ONLY SCROLLBARS_NONE 描 述 创建和显示水平滚动条和垂直滚动条 创建和显示垂直滚动条 创建和显示水平滚动条 没有任何滚动条 值 0 1 2 3

Java实用教程 public void append(String str) 将非空str字符串文本添加到文本区域中。

public void insert(String str, int pos)
在指定位置pos插入非空字符串str。 public void replaceRange(String str, int start, int end) 将start开始位置到end结束位置的字符串替换成非空字符串 str,其中start位置的字符被替换,end位置的字符仍保留。 public void setText(String t) 将文本框的内容设置为特定文本t。

Java实用教程 public String getText() 返回文本框的内容,返回值为字符串。 public void setEditable(boolean b) 设定文本框内容是否是用户可编辑的。b为false时,表示不 可编辑。b为true时,表示可编辑。通常创建一个文本框时,默 认为用户可编辑的。 public int getColumns() 返回列数。 public int getRows() 返回行数。

Java实用教程 【例6.8】测试TextArea类,用户界面如图6.9所示。源程序 代码如下: //程序文件名UseTextArea.java

import java.awt.*;
import java.applet.*; import java.applet.Applet; public class UseTextArea extends Applet { String str1 = new String(); String str2 = new String(); int i1,i2,i3; TextArea t1,t2,t3,t4,t5;//声明对象

Java实用教程 public void init() { t1 = new TextArea(); t2 = new TextArea(2,20); t3 = new TextArea("文本区域对象3"); t4 = new TextArea("文本区域对象4", 3, 10); t5 = new TextArea("文本区域对象5", 2, 24, TextArea.SCROLLBARS_BOTH); this.add(t1); this.add(t2); this.add(t3); this.add(t4); this.add(t5); }

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

Java实用教程 }

public void paint(Graphics g)
{ g.drawString("第三个对象的文本内容为:" + str1,40,400); g.drawString("第四个对象的文本内容为:" + str2,40,420); g.drawString("第四个对象的行数为:" + i1,40,440);

g.drawString("第五个对象的列数为:" + i2,40,460);
g.drawString("第五个对象的滚动条情况为:" + i3,40,480); }

};

Java实用教程

图6.9 TextArea对象的界面

Java实用教程

6.2 布 局
6.2.1 流式布局器 流式布局将组件按照从左到右的顺序自然排列,是缺省的设 置方式。其构造函数如下: FlowLayout() 构建一个新的流式布局器,中央对齐,对象之间以5单元水 平和垂直间隔。 FlowLayout(int align) 构建一个新的流式布局器,通过align设置对齐方式,对象之 间以5单元水平和垂直间隔。 FlowLayout(int align, int hgap, int vgap) 构建一个新的流式布局器,通过align设置对齐方式,对象之 间以hgap单元水平间隔并以vgap单元垂直间隔。

Java实用教程 6.2.2 边缘布局器 边缘布局器是一个分为北(NORTH)、南(SOUTH)、东

(EAST)、西(WEST)和中央(CENTER)五部分的容器。其构造函
数如下: BorderLayout() 构建一个新的边缘布局,对象之间没有间隔。 BorderLayout(int hgap, int vgap) 构建一个新的边缘布局,对象之间的水平间隔为hgap,垂 直间隔为vgap。

Java实用教程 6.2.3 面板 面板是最简单的容器类,应用程序可以在面板提供的空间 里放置任意组件及其它的面板。 Panel() 使用缺省的布局管理器创建一个新的面板。缺省的布局管 理器为流式管理器。 Panel(LayoutManager layout) 用指定的layout布局管理器创建一个面板。 public void setLayout(LayoutManager mgr) 设置布局管理器。

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

Checkbox chMale, chFemale;

Java实用教程
CheckboxGroup c; TextArea taText; Choice chJob; Button btnOk,btnCancel; Panel p1,p2,p3,p4,p5,p6,p7,p8,p9; public void init() { lblName = new Label("姓名:"); lblNumber = new Label("身份证号:"); lblSex = new Label("性别"); lblJob = new Label("职业");

lblText = new Label("个性化宣言:");

Java实用教程
tfName = new TextField(23);
tfNumber = new TextField(20); taText = new TextArea(10,20);

c = new CheckboxGroup();
chMale = new Checkbox("男",c,true); chFemale = new Checkbox("女",c,false);

chJob = new Choice();
chJob.add("计算机业"); chJob.add("医生");

chJob.add("教师");
chJob.add("军队"); btnOk = new Button("确定");

btnCancel = new Button("取消");

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

Java实用教程

p3.add(chMale); p3.add(chFemale); p4.add(lblJob); p4.add(chJob); p5.add(p3); p5.add(p4); p6.setLayout(new BorderLayout()); p6.add(p1,BorderLayout.NORTH); p6.add(p2,BorderLayout.CENTER); p6.add(p5,BorderLayout.SOUTH); p7.add(lblText,BorderLayout.NORTH); p7.add(taText,BorderLayout.CENTER);

Java实用教程 p8.setLayout(new FlowLayout(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.3 java.swing包
6.3.1 基本组件
JButton为轻量级按钮组件,对应着Button组件类。 JLabel为轻量级标签组件,对应着Label组件类。 JCheckBox为轻量级复选框,对应CheckBox类。

JradioButton为轻量级单选按钮,需要添加在ButtonGroup组中。
JRadioButton jMale = new JRadioButton("男"); JRadioButton jFemale = new JRadioButton("女");

Java实用教程 ButtonGroup group = new ButtonGroup(); group.add(jMale);

group.add(jFemale);
JComoBox对应Choice组件,但添加项的方法不同,使用的 是addItem方法,例如: JComboBox cmbJob = new JComboBox(); cmbJob.addItem("计算机业"); cmbJob.addItem("医生"); cmbJob.addItem("教师");

Java实用教程 cmbJob.addItem("军队"); JTextField组件为允许对单行文本进行编辑的轻量级组件, 对应TextField类。 JTextArea组件用于在多行区域中显示纯文本并进行编辑。 Jpanel为轻量级面板控件,对应原来的Panel类。 JApplet类继承自Applet类。

Java实用教程 6.3.2 JTable JTable是用于显示和编辑的两维表单元。它的构造函数和常 用方法为: public JTable() 构造一个空的JTable对象。 public void setModel(TableModel dataModel)

为表对象设置数据模型dataModel,并将新数据模型进行注册。

DefaultTableModel是一个实现模型,使用一系列Vector对象 实现表单元数据的填充。它的构造函数和常用方法为:
public DefaultTableModel()

构造函数。

Java实用教程 public void addColumn(Object columnName) 添加一列标题。

public void addRow(Vector rowData)
在模型对象的末尾添加一行Vector对象的数据。

构造Jtable对象的步骤如下:
(1) 构造一个空JTable对象。 JTable tblInf = new JTable(); (2) 构造DefaultTableModel对象,用setModel方法将此对象 绑定到JTable上。

DefaultTableModel dtm = new DefaultTableModel();

Java实用教程 (3) 具体实现DefaultTableModel对象(addColomn方法实现列 标题设置,addRow方法实现数据行添加)。 ① 初始化Vector列表,添加列标题。 Vector vCdata = new Vector(); vCdata.add("姓名"); vCdata.add("身份证号"); vCdata.add("性别");

tblInf.setModel(dtm);
for (int i=0; i<vCdata.size(); i++) dtm.addColumn((String)vCdata.elementAt(i));

Java实用教程 ② 初始化Vector列表,添加行数据。 Vector vRdata = new Vector(); vRdata.add("王飞"); vRdata.add("111122197904290902"); vRdata.add("男"); dtm.addRow(vRdata); ③ JTable没有内嵌滚动功能,将之放入JScrollPane对象中 并进行显示。 JScrollPane s = new JScrollPane(tblInf); getContentPane().add(s,BorderLayout.CENTER);

Java实用教程 6.3.3 Jtree JTree控件用于显示一系列分层数据,即树状显示。它的构 造函数和常用方法为: public void setModel(TreeModel newModel) 设置提供数据的TreeModel模型。TreeModel是一个接口, 接口内实现的类为DefaultTreeModel类,DefaultTreeModel是一 个使用TreeNodes的简单树数据模型,下面给出它的构造函数。 public DefaultTreeModel(TreeNode root)

Java实用教程

创建根结点为root的树,其中每个结点都可以有子结点。 TreeNode是一个接口,它包含一个DefaultTreeNode类, DefaultTreeNode类表达了一个树型数据结构中具有一般意义的 结点。每个树结点至多有一个父结点,0个或多个子结点。其构 造函数为:
public DefaultMutableTreeNode(Object userObject)

创建一个无父结点、无子结点的树结点。例如
public DefaultMutableTreeNode f = new DefaultMutableTreeNode("个人信息"); public add(MutableTreeNode newChild) 将newChild结点添加到树结点的末尾,使之称为当前结点的 子结点。

Java实用教程 创建树结构的步骤如下: (1) 构建JTree对象。 JTree tree = new JTree(); (2) 构造DefaultMutableTreeModel对象,使用SetModel方法 将DefaultMutableTreeModel对象绑定到Jtree对象。 tree.setModel(new DefaultTreeModel(root));

Java实用教程 (3) 构造树。 ① 构造根结点。 DefaultMutableTreeNode root; ② 构造分支结点,添加到根结点。 DefaultMutableTreeNode NodeName, NodeNumber, NodeSex; NodeName = new DefaultMutableTreeNode("姓名"); NodeNumber = new DefaultMutableTreeNode("身份证号"); NodeSex = new DefaultMutableTreeNode("性别");

root.add(NodeName);
root.add(NodeNumber); root.add(NodeSex);

Java实用教程 ③ 添加叶子结点并添加到分支结点。 leafName = new DefaultMutableTreeNode("王飞");

leafNumber = new
DefaultMutableTreeNode("111122197904290902");

leafSex = new DefaultMutableTreeNode("男");
NodeName.add(leafName); NodeNumber.add(leafNumber); NodeSex.add(leafSex);

Java实用教程 ④ 使用DefaultMutableTreeModel的构造函数,将根结点作 为参数构造树结构中的数据。

DefaultTreeModel dTree = new DefaultTreeModel(root);
⑤ JTree没有内嵌的滚动属性,较大的树状结构可以显示在 JScrollPane上。 JScrollPane scroll = new JScrollPane(tree); getContentPane().add(scroll);

Java实用教程 6.3.4 实例 【例6.10】 测试java.swing包提供的轻量级组件的例子,主 类TestSwing扩展于JFrame类,显示结果如图6.11所示。界面分 为三部分,上一部分和上例中的显示结果一一对应,中间一部 分为table表记录,下面的部分为树状显示结构。源程序代码如 下: //文件名为:TestSwing.java import java.awt.*;

import java.util.*;
import javax.swing.*; import javax.swing.tree.*; import javax.swing.table.*;

Java实用教程

import javax.swing.ButtonGroup;
public class TestSwing extends JFrame { JLabel lblName = new JLabel("姓名:"); JLabel lblNumber = new JLabel("身份证号"); JLabel lblSex = new JLabel("性别"); JLabel lblJob = new JLabel("职业"); JLabel lblText = new JLabel("个性化宣言"); JTextField tfName = new JTextField(23); JTextField tfNumber = new JTextField(20); JTextArea taText = new JTextArea(5,20);

JRadioButton jMale = new JRadioButton("男");

Java实用教程

JRadioButton jFemale = new JRadioButton("女");
ButtonGroup group = new ButtonGroup(); JComboBox cmbJob = new JComboBox(); JButton btnOk = new JButton("确定"); JButton btnDisplay = new JButton("取消");

JTable tblInf = new JTable();
DefaultTableModel dtm = new DefaultTableModel(); //布局设置 JTree tree = new JTree(); JPanel p1 = new JPanel(); JPanel p2 = new JPanel();

Java实用教程

JPanel p3 = new JPanel();
JPanel p4 = new JPanel(); JPanel p5 = new JPanel(); JPanel p6 = new JPanel(); JPanel p7 = new JPanel(new BorderLayout());

JPanel p8 = new JPanel();
JPanel p9 = new JPanel(new BorderLayout()); public TestSwing() { group.add(jMale); group.add(jFemale);

Java实用教程 cmbJob.addItem("计算机业"); cmbJob.addItem("医生"); cmbJob.addItem("教师"); cmbJob.addItem("军队"); p1.add(lblName); p1.add(tfName); p2.add(lblNumber); p2.add(tfNumber); p3.add(lblSex); p3.add(jMale); p3.add(jFemale); p4.add(lblJob); p4.add(cmbJob);

Java实用教程 p5.add(p3); p5.add(p4); p6.setLayout(new BorderLayout()); p6.add(p1,BorderLayout.NORTH); p6.add(p2,BorderLayout.CENTER); p6.add(p5,BorderLayout.SOUTH); p7.add(lblText,BorderLayout.NORTH); p7.add(taText,BorderLayout.CENTER); p8.setLayout(new FlowLayout(FlowLayout.CENTER,30,10)); p8.add(btnOk); p8.add(btnDisplay); p9.add(p6,BorderLayout.NORTH); p9.add(p7,BorderLayout.CENTER);

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

Java实用教程

Vector vCdata = new Vector(); vCdata.add("姓名"); vCdata.add("身份证号"); vCdata.add("性别"); tblInf.setModel(dtm); for (int i=0; i<vCdata.size(); i++) dtm.addColumn((String)vCdata.elementAt(i)); Vector vRdata = new Vector(); vRdata.add("王飞"); vRdata.add("111122197904290902"); vRdata.add("男"); dtm.addRow(vRdata);

Java实用教程

}
//设置树 public void setTree() { DefaultMutableTreeNode root; DefaultMutableTreeNode NodeName, NodeNumber, NodeSex; DefaultMutableTreeNode leafName, leafNumber, leafSex; root = new DefaultMutableTreeNode("个人信息"); NodeName = new DefaultMutableTreeNode("姓名"); leafName = new DefaultMutableTreeNode("王飞"); NodeNumber = new DefaultMutableTreeNode("身份证号");

leafNumber = new DefaultMutableTreeNode("111122197904290902");

Java实用教程 NodeSex = new DefaultMutableTreeNode("性别"); leafSex = new DefaultMutableTreeNode("男"); root.add(NodeName); root.add(NodeNumber); root.add(NodeSex);

NodeName.add(leafName);
NodeNumber.add(leafNumber); NodeSex.add(leafSex); //设置Tree渲染的基本属性 tree.getSelectionModel().setSelectionMode( TreeSelectionM odel.SINGLE_TREE_SELECTION );

Java实用教程 tree.setShowsRootHandles( true ); //树不可以编辑 tree.setEditable( false ); tree.setModel(new DefaultTreeModel(root)); } public static void main(String[] args) { TestSwing ts = new TestSwing();

ts.setSize(400,450);
ts.show(); }

}

Java实用教程

图6.11 显示结果

Java实用教程

习 题
1. 设计一个界面,如图6.12所示。其中身份证一栏有四项, 分别为身份证、军人证、学生证和护照。

图6.12

Java实用教程 2. 设计一个标签区域和三个滚动条,滚动条的取值范围均 为0~255,即使得滚动条的取值对应颜色对象的红、绿、蓝三

个基色的值,初始标签颜色为红色。
3. 用java.swing包中的类设计如图6.12所示的界面,然后进

行详细的布局设计。
4. 图6.13中的Xuesheng表,代表了每个学生的基本信息,

在Applet界面上设计此表,并依次进行记录的添加。

Java实用教程

图6.13 Xuesheng表的记录显示

Java实用教程

5. 用树状结构显示如图6.14所示的部分文件系统目录,要
求节点的名字为文件夹的名字或者文件的名字,图片无需显示。 注意ppt文件夹下含有两个文件,分别为6_10.ppt和6_10.vsd。 图 6 14 部 分 文 件 系 统 目 录

.

Java实用教程

第7章 异常、事件和多线程机制
7.1 异常

7.2 事件
7.3 多线程机制

习 题

Java实用教程

7.1 异 常
7.1.1 定义 异常是指当程序中某些地方出错时创建的一种特殊的运行 时错误对象。Java创建异常对象后,就发送给Java程序,即抛出 异常(throwing an exception)。程序捕捉到这个异常后,可以编写 相应的异常处理代码进行处理。使用异常处理可以使得程序更 加健壮,有助于调试和后期维护。

Java实用教程 7.1.2 异常类 由继承类图可以看出,Throwable类派生了两个类: Exception类和Error类,其中Error类系统保留,而Exception类供 应用程序使用,它下面又派生出几个具体的异常类,都对应着

一项具体的运行错误,如图7.1所示。

Java实用教程
Throwable类 Error类 Exception类 … IllegalAccessException 类

ClassNotFoundException 类

IOException类 NullPointerException 类 InterruptedException 类

MalformedURLException类

图7.1 异常类图

Java实用教程 Exception类中常用的方法为: public String toString() 返回异常的简短描述。 public String getMessage() 返回异常的详细信息描述。

异常类分为系统定义的异常和用户自定义的异常。

Java实用教程

1. 系统定义的异常
图7.1中Exception派生的这些子类都是系统事先定义好并包

含在Java类库中的,系统定义的异常对应着一些系统错误,如
中断、文件没找到等错误。表7.1列举了一些常见的系统异常类。 表7.1 常见的系统异常类
系统定义的运行异常 ArrayIndexOutofBoundsException 类 ArithmaticException 类 ClassNotFoundException 类 InterruptedException 类 IOException 类 MalformedURLException 类 NullPointerException 类 SecurityException 类 对应的系统错误 数组越界使用 算术错误,除数为 0 未找到欲装载使用的类 中断错误,线程操作时可能引发 输入、输出错误 输入的 URL 网址格式有错误 空的尚未分配内存的对象 安全错误,如 Applet 欲读写客户端文件时引发

Java实用教程 2. 用户自定义异常 用户自定义异常用来处理用户应用程序中的特定逻辑的运 行错误,用户自定义的异常类通常继承自Exception类,例如: public class UserDefineException extends Exception {

public UserDefineException(String msg)
{ super(msg); } };

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

Java实用教程 try { 语句块; } catch(异常类 异常类参数名) { 异常处理语句块; } finally { try或者catch语句完毕后必须执行的语句(通常用于关闭文件 流对象或者数据库对象等);

}

Java实用教程 1. 直接抛出异常 例如: public void myMethod() { try { urlName = new URL(""); getAppletContext().showDocument(urlName,"right"); } catch(MalformedURLException e) { System.out.println(e.getMessage()); } }

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

Java实用教程 2. 间接抛出异常 例如:

public void myMethod() throws MalformedURLException
{

urlName = new URL("");
getAppletContext().showDocument(urlName,"right");

}
在方法后面直接抛出。

Java实用教程

3. 综合方法 例如: public void myMethod() throws MalformedURLException { try { urlName = new URL(""); getAppletContext().showDocument(urlName,"right"); } catch(MalformedURLException e) { System.out.println(e.getMessage()); } }

Java实用教程 7.1.4 多异常的处理 多异常的处理使用多个catch来捕捉不同类的异常,Java中

对catch块的数量没有限制。格式如下:
Try { ... } catch(异常类1 标识符) {

Java实用教程 ... }

catch(异常类2 标识符)
{ ... } finally

{
... }

Java实用教程 【例7.1】 测试多异常处理和自定义异常。源程序代码如下: //程序文件名UseMultiException.java public class UseMultiException extends Exception { static String str1; static String str2; public static void main(String[] args) { int i1 = 0; int i2 = 0; str1 = new String(args[0]); str2 = new String(args[1]); String strResult = new String(); try {

Java实用教程 read(str1, str2); i1 = Integer.parseInt(str1); i2 = Integer.parseInt(str2); int result = i1/i2; strResult = String.valueOf(result);

} catch(NumberFormatException e) { strResult = "错误的数字:" + e.getMessage(); } catch(ArithmeticException e) { strResult = "被0除错误:" + e.getMessage(); }

Java实用教程

str1 = s1.trim(); str2 = s2.trim(); if (str1.equals("0")) { throw (new UserDefineException("本系统0不能为被除数")); }
} }; class UserDefineException extends Exception { public UserDefineException(String msg) { super(msg); } };

Java实用教程

具体运行测试如下,结果如图7.2所示。
java UseMultiException 2gf 5 数字格式出错。 java UseMultiException 2gf 0 java UseMultiException 2 0 被0除出错。 java UseMultiException 0 3

数字格式出错,下面的程序代码不再执行,无法抛出第二个异常。

引发用户自定义错误。
java UseMultiException 9 3 9/3的答案为3。

Java实用教程

图7.2 异常测试输出

Java实用教程

7.2 事 件
事件用于描述程序、系统和程序使用者之间的各种活动。 这些事件由系统事先定义好,当用户在图形界面上单击控件或 双击鼠标时就可能引发某个事件,而用户程序中需要编制相应

的代码来对这些事件做出处理。
1. 事件源

图形用户界面上每个可能产生事件的组件称为事件源。

Java实用教程 2. 事件监听者 Java系统中注册的用于接收特殊事件的类。不同的事件对 应着不同的监听者,要想事件被监听者监听并处理,则需先将 事件源注册到监听者。

3. 事件处理流程
事件源触发事件并将事件作为一个参数传递给监听者,监

听者实现某个接口中的抽象方法,从而实现对事件的处理。
Java的事件处理机制是一个委托事件模型,如图7.3所示。

Java实用教程

事件源 注册:add…Listener方法 触发事件 注册 …Event事件 调用并传递参数 监听者:…Listener 实现接口方法

图7.3 Java事件处理机制

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

Java中常用的事件和相应的事件监听者如表7.2所示。

Java实用教程 表7.2 常用事件及其监听者

事件描述 动作事件 文本事件 选择事件 调整事件 鼠标事件 键盘事件

事 件 类 ActionEvent TextEvent ItemEvent AdjustmentEvent MouseEvent KeyEvent

监 听 者 ActionListener TextListener ItemListener AdjustmentListener MouseListener KeyListener

Java实用教程 7.2.1 动作事件(ActionEvent) ActionEvent包含一个事件,该事件为执行动作事件 ACTION_PERFORMED。触发这个事件的动作为: (1) 点击按钮。 (2) 双击列表中的选项。 (3) 选择菜单项。 (4) 在文本框中输入回车。

Java实用教程 常用方法如下: public String getActionCommand() 返回引发某个事件的命令按钮的名字,如果名字为空,那 么返回标签值。 public void setActionCommand(String command) 设置引发事件的按钮的名字,默认设置为按钮的标签。

Java实用教程 【例7.2】测试动作事件。源程序代码如下: //程序文件名UseButton.java import java.awt.*; import java.awt.event.*; import java.applet.*; import java.applet.Applet; public class UseButton extends Applet implements ActionListener { String str1 = new String(); Button b1; //声明按钮对象; Button b2; Color c; public void init() {

Java实用教程

b1 = new Button(); b2 = new Button("按钮对象2"); //添加事件监听者 b1.addActionListener(this); b2.addActionListener(this); this.add(b1); this.add(b2);
} public void start() { b1.setLabel("按钮对象1"); str1 = b2.getLabel(); repaint(); }

Java实用教程 public void paint(Graphics g) { g.setColor(c); g.drawString("引发事件的对象的标签:" + str1, 40,60); } //实现接口中的方法,响应动作事件 public void actionPerformed(ActionEvent e) { String arg = e.getActionCommand(); if(arg == "按钮对象1") { c = Color.red; str1 = "按钮对象1"; }

Java实用教程 else if(arg == "按钮对象2") { c = Color.blue; str1 = "按钮对象2"; } repaint(); }

}

Java实用教程 单击“按钮对象1”,引发对象1的单击事件,输出结果如 图7.4所示;单击“按钮对象2”,引发对象2的单击事件,输出 结果如图7.5所示。

图7.4 单击“按钮对象1”的输出

Java实用教程

图7.5 单击“按钮对象2”的输出

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

Java实用教程 接口中的方法为: public void textValueChanged(TextEvent e)

当文本发生改变时调用。
public Object getSource()

发生事件的对象,从EventObject继承来的方法。

Java实用教程

【例7.3】测试文本事件。源程序代码如下: //程序文件名UseTextEvent.java import java.awt.*; import java.awt.event.*; import java.applet.*; import java.applet.Applet; public class UseTextEvent extends Applet implements ActionListener, TextListener { TextField tOld; TextArea tNew; Panel p; public void init() {

Java实用教程 tOld = new TextField(25); tNew = new TextArea(8,25); //添加事件监听者 tOld.addActionListener(this); tOld.addTextListener(this);

//设置界面
p = new Panel(new BorderLayout()); p.add(tOld,BorderLayout.NORTH); p.add(tNew,BorderLayout.SOUTH); add(p);

}

Java实用教程 //响应文本事件 public void textValueChanged(TextEvent e) { if(e.getSource() == tOld) tNew.setText(tOld.getText()); } //响应动作事件 public void actionPerformed(ActionEvent e) { if(e.getSource() == tOld) tNew.setText(""); } };

Java实用教程 在文本框中键入“你好,这是文本事件同步”字符串,可 以看见文本区域中的字符跟随变化,如图7.6所示,这是响应文 本事件。键入字符串后按回车键,则发生响应动作事件,将文 本区域清空,如图7.7所示。

图7.6 响应文本事件

Java实用教程

图7.7 响应动作事件

Java实用教程 7.2.3 选择事件(ItemEvent) 选择事件中包含以事件为代表的选择项,选中状态发生变 化的事件ITEM_STATE_ CHANGED。引发的动作为: (1) 改变列表类List对象选项的选中或不选中状态。 (2) 改变下拉列表类Choice对象选项的选中或不选中状态。 (3) 改变复选按钮类Checkbox对象的选中或不选中状态。

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

Java实用教程 【例7.4】测试选择事件。分别对设置颜色的复选框和有三 种字号10、12和14的组合框进行选择时,标签的颜色和字体发 生变化。源程序代码如下:

//程序文件名UseItemEvent.java
import java.awt.*;

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

import java.applet.Applet;
public class UseItemEvent extends Applet implements ItemListener {

Java实用教程

Checkbox cDisp; Button btnDisp; Choice cFont; public void init() { cDisp = new Checkbox("红色"); btnDisp = new Button("颜色显示"); cFont = new Choice(); cFont.add("10"); cFont.add("12"); cFont.add("14"); //添加事件 cDisp.addItemListener(this);

Java实用教程 cFont.addItemListener(this); add(cDisp); add(cFont); add(btnDisp); } //接口事件 public void itemStateChanged(ItemEvent e) { Checkbox temp; Choice temp2; Font oldF; //复选框 if(e.getItemSelectable() instanceof Checkbox) {

Java实用教程 temp = (Checkbox)(e.getItemSelectable()); //选中为红色,否则为蓝色

if(temp.getState())
btnDisp.setBackground(Color.red); else btnDisp.setBackground(Color.blue); } //组合框 if(e.getItemSelectable() instanceof Choice) {

oldF = btnDisp.getFont();

Java实用教程 temp2 = (Choice)(e.getItemSelectable()); String s = temp2.getSelectedItem();

//设置字体
btnDisp.setFont(new Font(oldF.getName(),oldF.getStyle(),Integer.parseInt(s))); } }

}

Java实用教程 当选中红色复选框和组合框中的字号为14时,显示界面如 图7.8所示;当未选中红色复选框和选中组合框中的字号为10时, 显示界面如图7.9所示。

图7.8 选中红色和字号为14的界面

Java实用教程

图7.9 未选中红色和字号为10的界面

Java实用教程 7.2.4 调整事件(AdjustmentEvent) 调整事件包含一个事件,即

ADJUSTMENT_VALUE_CHANGED事件,当操纵滚动条改变
其滑块位置时引发动作。AjustEvent的方法如下: public Adjustable getAdjustable() 返回引发事件的对象。

public int getValue()
返回调整事件中的当前值。

Java实用教程 public void addAdjustmentListener(AdjustmentListener l) 添加调整监听者来接收来自对象的AdjustmentEvent实例。

public interface AdjustmentListener extends EventListener
接收调整事件的监听接口,有一个方法: public void adjustmentValueChanged(AdjustmentEvent e) 可在调整改变时调用这个值。

Java实用教程 【例7.5】测试调整事件。设置一个水平滚动条,取值为 1~36,随着滑块的变化,滚动条的值将显示在文本区域中, 并且字体大小也会跟随变化。源程序代码如下:

//程序文件名UseAdjustmentEvent.java
import java.awt.*; import java.awt.event.*; import java.applet.*; import java.applet.Applet; public class UseAdjustmentEvent extends Applet implements AdjustmentListener

{

Java实用教程 Scrollbar s; TextArea txtValue; Panel p; public void init() { s = new Scrollbar(Scrollbar.HORIZONTAL,0,1,10,36); //添加监听者

s.addAdjustmentListener(this);
txtValue = new TextArea(5,25); //界面布局

p = new Panel(new BorderLayout());
p.add(s,BorderLayout.NORTH);

Java实用教程 p.add(txtValue,BorderLayout.SOUTH); add(p); } public void start() { } public void adjustmentValueChanged(AdjustmentEvent e) { int value; Font oldF; if(e.getAdjustable() == s) { //得到滚动条的值

Java实用教程 value = e.getValue(); //将值写入文本区域

txtValue.setText(new Integer(value).toString());
//按照滚动条的值设置字体 oldF = txtValue.getFont();

txtValue.setFont(new Font(oldF.getName(),oldF.getStyle(),value)); }

}
}

Java实用教程

随着滚动条的变化,可以看见文本区域中的取值以及大小
都会跟随变化,取值为10和取值为35时的效果各不相同,如图 7.10和图7.11所示。

图7.10 字号为10的界面

Java实用教程

图7.11 字号为35的界面

Java实用教程 7.2.5 鼠标事件(MouseEvent) 表明画布或界面组件中发生的鼠标事件,包含按下鼠标、 释放鼠标、单击鼠标、进入部件的地理位置的鼠标事件和退出 部件的地理位置的鼠标事件,以及鼠标移动事件(鼠标移动和

鼠标拖动)。
鼠标使用addMouseListener方法注册,通过MouseListener

接收鼠标事件;鼠标还可以使用addMouseMotionListener方法
注册,通过MouseMotionListener监听者监听鼠标移动事件。

Java实用教程 监听者中有具体的方法分别针对上述具体的鼠标事件,系 统能够自动分辨鼠标事件的类型并调用相应的方法,所以只需 编码实现相应的代码就可以了。 public int getButton() 返回哪个按钮发生变化。 public int getClickCount() 返回与这个事件相关的鼠标单击的次数。 public Point getPoint() 返回同源部件相对的事件发生的x、y位置。

public int getX()
返回同源部件相对的事件发生的x位置。 public int getY()

返回同源部件相对的事件发生的y位置。

Java实用教程 【例7.6】测试按钮和画布的鼠标事件,包括单击、按下、 进入和退出等。鼠标事件的演示如图7.12和7.13所示。源程序 代码如下:

//程序文件名UseMouseEvent.java
import java.awt.*; import java.awt.event.*; import java.applet.*; import java.applet.Applet; public class UseMouseEvent extends Applet implements MouseListener, MouseMotionListener {

Java实用教程

Button btn;
public void init() { btn = new Button("演示鼠标事件"); add(btn); //给按钮添加鼠标事件和鼠标移动事件 btn.addMouseListener(this); btn.addMouseMotionListener(this);

//给画布添加鼠标事件和鼠标移动事件
this.addMouseListener(this); this.addMouseMotionListener(this);

}

Java实用教程

//单击事件 public void mouseClicked(MouseEvent e) { Point p = new Point(); if(e.getSource() == btn) { if(e.getClickCount() == 1) { btn.setLabel("单击鼠标"); } else if(e.getClickCount() == 2) { btn.setLabel("双击鼠标"); }

Java实用教程 } else

{
if(e.getClickCount() == 1) {

p = e.getPoint();
showStatus(p.x + "," + p.y + "单击鼠标"); }

else if(e.getClickCount() == 2)
{ p = e.getPoint(); showStatus(p.x + "," + p.y + "双击鼠标");

Java实用教程 } } } //进入事件 public void mouseEntered(MouseEvent e) { if(e.getSource() == btn) btn.setLabel("进入Button"); else showStatus("进入Applet"); } public void mouseExited(MouseEvent e) { if(e.getSource() == btn) btn.setLabel("退出Button");

Java实用教程

else
showStatus("退出Applet"); } //按下事件 public void mousePressed(MouseEvent e) { if(e.getSource() == btn) btn.setLabel("按下鼠标"); else showStatus("按下鼠标"); } //释放事件 public void mouseReleased(MouseEvent e) {

Java实用教程 if(e.getSource() == btn) btn.setLabel("松开鼠标"); else showStatus("松开鼠标"); } //移动事件 public void mouseMoved(MouseEvent e) { if(e.getSource() == btn) btn.setLabel("移动鼠标"); else
showStatus("移动鼠标,新位置" + e.getX() + "," + e.getY());

}

Java实用教程 //拖动事件 public void mouseDragged(MouseEvent e)

{
if(e.getSource() == btn) btn.setLabel("拖动鼠标"); else showStatus("拖动鼠标");

}
};

Java实用教程

图7.12 状态行提示鼠标移动位置

Java实用教程

图7.13 提示“按下鼠标”

Java实用教程 7.2.6 键盘事件(KeyEvent) 键盘事件有三个:键盘按键按下,按键释放,按键被敲击。 常用方法如下: public char getKeyChar() 返回事件中键的字符。

public int getKeyCode()
返回整数键码。 public static String getKeyText(int keyCode) 返回描述这个键码的字符串,例如“HOME”、“F1”或者“A” 等。

public interface KeyListener extends EventListener
用来接收键盘事件。使用方法addKeyListener注册。

Java实用教程

针对键盘的三个事件接口提供相应的方法进行处理,具体方法如下: public void keyPressed(KeyEvent e) 按键时引发事件处理。 public void keyReleased(KeyEvent e) 释放键时引发事件处理。 public void keyTyped(KeyEvent e) 键入键时引发事件处理。

Java实用教程 例如,按键处理事件如下: public void keyPressed(KeyEvent e)

{
char ch = e.getKeyChar(); if(ch =='Y' || ch == 'y') txt.setText ("同意"); else if ch == 'N' || ch == 'n' ()

txt.setText ("反对");
else txt.setText ("无效");

}

Java实用教程

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

Java实用教程 线程存在一个生命周期,由以下方法体现: (1) start()方法:启动一个线程。 (2) run()方法:定义该线程的动作。 (3) sleep()方法:使线程睡眠一段时间,单位为ms。 (4) suspend()方法:使线程挂起。

(5) resume()方法:恢复挂起的线程。
(6) yield()方法:把线程移到队列的尾部。 (7) stop()方法:结束线程生命周期并执行清理工作。 (8) destroy()方法:结束线程生命周期但不做清理工作。 其中最常用的是方法start()、run()、sleep()、stop()。

Java实用教程 7.3.2 线程类和Runnable接口 1. 建立Thread类的子类 class myThread extends Thread { ... public void start()//启动线程 { ... } public void run()//运行线程 { ... } }

Java实用教程

【例7.7】多线程实例,主函数给予调用,调用情况如图 7.14所示。源程序代码如下: public class MThread { public static void main(String[] args) { System.out.println("Hello World!"); thread2 t1 = new thread2("线程实例1"); //创建线程实例 t1.start(); //调用 thread2 t2 = new thread2("线程实例2"); t2.start(); thread2 t3 = new thread2("线程实例3"); t3.start(); } }

Java实用教程

//自定义线程类thread2 class thread2 extends Thread { Thread thread; //定义线程实例 String str; //构造函数 public thread2(String str) { this.str = str; } //启动线程 public void start() { thread = new Thread(this); thread.start(); }

Java实用教程 public void run() { int i = 0; while(thread != null) { try { //计数到5时睡眠10秒 if(i == 5) sleep(10000); } catch(Exception e) {

Java实用教程

System.out.println(e.getMessage());
}

System.out.println(str);
i++; } } };

Java实用教程

图7.14 多线程操作界面

Java实用教程 2. 实现接口Runnable public interface Runnable

Runnable接口可以由任意试图实现线程机制的类来实现。
接口包含一个run方法。 public void run() 对象实现Runnable接口时,创建一个线程,启动线程导致 对象run方法的调用。 实现接口Runnable进行多线程设计的方法较为常用。下面 给出一个例子。

Java实用教程 【例7.8】编写Applet,实现Runnable接口进行简单的动画演 示:三幅图片依次上移,如图7.15所示。源程序代码如下:
//程序文件名为UseRunnable.java

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

public class UseRunnable extends Applet implements Runnable
{ Thread t; Image imgs[]; int high,h1,h2,h3; public void init() {

Java实用教程 high = getHeight()/3; h1 = high; h2 = high * 2; h3 = high * 3;

imgs = new Image[3];
for (int i = 0; i < 3; i ++) { } }

imgs[i] = getImage(getDocumentBase(),"image" + (i+1) + ".gif");

public void start()
{

Java实用教程 t = new Thread(this); t.start(); } public void stop() { t = null; } //实现接口的run方法,获得动画效果 public void run() { while( t != null) { try {

Java实用教程

Thread.sleep(100); repaint(); h1 --; //上移,到顶点时睡眠 if(h1 == 0) { Thread.sleep(3000); h2 = high; } //上移,到顶点时睡眠 h2 --; if(h2 == 0) { Thread.sleep(3000); h3 = high; }

Java实用教程 //上移,到顶点时睡眠 h3--; if(h3 == 0) { Thread.sleep(3000); h1 = high; } } catch(InterruptedException e) { System.out.println(e.getMessage()); }

}
}

Java实用教程

public void paint(Graphics g)
{ //三幅图片依次显示 g.drawImage(imgs[0],0,h1,this); g.drawImage(imgs[1],0,h2,this); g.drawImage(imgs[2],0,h3,this); } public void update(Graphics g)

{
paint(g); }

};

Java实用教程

图7.15 动画界面

Java实用教程

习 题
1. 自定义一个用户异常,用于数值运算时在输入的字符中

检测非数字字符,并编写抛出异常时的提示“使用非法字符”,
测试异常。 2. 为第6章习题1中图6.12所示的“提交”按钮添加动作事 件,用来收集界面上输入的个人信息,并在原有界面上添加一 个文本区域,将数据输出到文本区域中。 3. 为第6章习题2添加调整事件,使得三个滚动条进行滑动 时,标签的颜色相应地发生变化。 4. 编写Applet,实现Runnable接口,使得界面上的一图片 持续做水平运动。

Java实用教程

第8章 输入输出技术
8.1 流式输入输出
8.2 基本输入输出流 8.3 文件处理类 8.4 对象流 习 题

Java实用教程

8.1 流式输入输出
所有的计算机程序都必须接收输入和产生输出。针对输入、

输出,Java提供了丰富的类库进行相应的处理,包括从普通的流
式输入输出到复杂的文件随机访问。计算机系统使用的信息都 是从输入经过计算机流向输出。这种数据流动就称为流(Stream)。 输入流指数据从键盘或者文件等输入设备流向计算机;输出流 指数据处理结果从计算机流向屏幕或文件等输出设备。

Java实用教程

在Java中,通过java.io包提供的类来表示流,基本的输入输
出流为InputStream和OutputStream。从这两个基本的输入输出流 派生出面向特定处理的流,如缓冲区读写流、文件读写流等。 Java定义的流如表8.1所示。 表8.1 Java定义的输入输出流
流 描 述 音频输入输出流 字节数组输入输出流 文件输入输出流 过滤器输入输出流 基本输入输出流 对象输入输出流 管道输入输出流 顺序输入输出流 字符缓冲输入输出流 输 入 流 AudioInputStream ByteArrayInputStream FileInputStream FilterInputStream InputStream ObjectInputStream PipedInputStream SequenceInputStream StringBufferInputStream 输 出 流 AudioOutputStream ByteArrayOutputStream FileOutputStream FilterOutputStream OutputStream ObjectOutputStream PipedOutputStream SequenceOutputStream StringBufferOutputStream

Java实用教程

8.2 基本输入输出流
8.2.1 InputStream类

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

Java实用教程 public boolean markSupported() throws IOException 测试流是否支持标志和复位。 public abstract int read() throws IOException 读取输入流中的下一个字节。 public int read(byte[] b) throws IOException 从输入流中读取字节并存储到缓冲区数组b中,返回读取的 字节数,遇到文件结尾返回-1。

Java实用教程 public int read(byte[] b, int off, int len) throws IOException 从输入流中读取len个字节并写入b中,位置从off开始。返 回写的字节数。 public void reset() throws IOException

重定位到上次输入流中调用的位置。
public long skip(long n) throws IOException

跳过输入流中n个字节,返回跳过的字节数,遇到文件结
尾返回-1。

Java实用教程 8.2.2 OutputStream类 OutputSteam是抽象类,代表输出字节流的所有类的超类。 public void close() throws IOException 关闭输出流,释放与流相关的系统资源。 public void flush() throws IOException 清洗输出流,使得所有缓冲区的输出字节全部写到输出设备中。 public void write(byte[] b) throws IOException 从特定字节数组b将b数组长度个字节写入输出流。 public void write(byte[] b, int off, int len) throws IOException

从特定字节数组b将从off开始的len个字节写入输出流。
public abstract void write(int b) throws IOException 向输出流写一个特定字节。

Java实用教程 8.2.3 系统输入输出对象 Java定义了两个流对象System.in和System.out,允许用户在 自己的程序中直接使用。System.in对象允许用户从键盘读取数 据,System.out对象可以产生屏幕输出。 【例8.1】使用流对象System.in和System.out,接收用户从键 盘上输入的数据并将数据输出到屏幕上。测试情况如图8.1所示。 源程序代码如下: //程序文件名为SystemIO.java

import java.io.*;

public class SystemIO {

Java实用教程 public static void main(String[] args) {

int bytes = 0;
byte buf[] = new byte[255]; System.out.println("\n请输入任意文本:");

try
{ //接收输入字符串 bytes = System.in.read(buf,0,255); System.out.println("这是你输入的文本行:"); String inStr = new String(buf,0,bytes);

Java实用教程 //输出字符串 System.out.println(inStr); } catch(IOException e) { System.out.println(e.getMessage());

}
} };

Java实用教程

图8.1 例8.1的屏幕显示

Java实用教程

8.3 文 件 处 理 类
8.3.1 FileInputStream类 FileInputStream(文件输入流)类是用来得到文件的输入字节 流。大部分方法继承于InputStream类。它的构造方法如下: FileInputStream(File file) 通过打开一个到实际文件的链接,创建一个文件输入流, 参数file是一个文件对象。

FileInputStream(String name)
通过打开一个到实际文件的链接,创建文件输入流,参数

name为文件的实际路径。

Java实用教程 【例8.2】使用FileInputStream对象打开源程序文件,源文件 的输出如图8.2所示。源程序代码如下:
//程序文件名为UseFileInputStream.java import java.io.*;

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

{
byte buf[] = new byte[2056]; try { //构造文件输入流

Java实用教程
FileInputStream fileIn = new FileInputStream("UseFileInputStream.java");

//存入缓冲buf int bytes = fileIn.read(buf,0,2056);

String inStr = new String(buf,0,bytes);
//输出文件内容 System.out.println(inStr);

}
catch(IOException e) {

System.out.println(e.getMessage());
} }

};

Java实用教程

图8.2 输出源文件内容

Java实用教程 8.3.2 FileOutputStream类 FileOutputStream(文件输出流)类是将数据写入File或 FileDescriptor对象的输出流。它的方法大都是从OutStream继承 来的,其构造方法如下: FileOutputStream(File file) 创建输出流写到特定的file对象。 FileOutputStream(File file, boolean append) 以追加的方式写入file对象。 FileOutputStream(FileDescriptor fdObj) 创建输出文件流到fdObj对象,代表一个到实际文件的链接。

Java实用教程 FileOutputStream(String name) 创建输出流,写到指定的name文件。 FileOutputStream(String name, boolean append) 是否以追加的方式写到指定的name文件。

Java实用教程

【例8.3】使用FileOutputStream对象,打开一个文件,写入 一行文本,然后追加一行从键盘接收的字符串(如图8.3的上部分 所示),文件内容如图8.3的下部分所示。源程序代码如下: //程序文件名为UseFileOutputStream.java
import java.io.*; public class UseFileOutputStream { public static void main(String[] args)

{
byte buf[] = new byte[255]; byte bufIn[] = new byte[255];

Java实用教程 try {

String str = "你好,这是已有的文本";
buf = str.getBytes(); //创建文件输出流对象 FileOutputStream fileOut = new FileOutputStream("Hello.txt"); //写入文件

fileOut.write(buf,0,buf.length);
fileOut.flush(); fileOut.close();

Java实用教程 System.out.println("\n请输入一行文本:"); //从键盘接收文本 int bytes = System.in.read(bufIn,0,255); //追加文本 fileOut = new FileOutputStream("Hello.txt",true); fileOut.write(bufIn,0,bytes); } catch(IOException e) { System.out.println(e.getMessage()); } } };

Java实用教程

图8.3 程序运行和写入的文件内容

Java实用教程 8.3.3 File类 用户接口和操作系统使用依赖于系统的路径字符串来命名 文件和目录。File类就表示这些文件和目录路径,它代表一个 抽象的依赖于系统的层次路径视图。File类允许用户向系统查

询该文件的所有信息,也可以使用类来创建新的目录或者删除
和重命名文件。 当用户需要获得有关文件的信息时,就需要创建一个File 类,而当File类用于文件读写时,通常与FileInputStream流相结 合。

Java实用教程 【例8.4】创建一个临时文件,写入一行数据,然后删除。 临时文件的周期说明如图8.4所示。源程序代码如下: //程序文件名为UseFile.java import java.io.*;

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

{

Java实用教程 File f = new File("temp.txt"); System.out.println("创建临时文件"); FileOutputStream fout = new FileOutputStream(f); PrintStream p = new PrintStream(fout); p.println("将这句话放入临时文件"); System.out.println("写临时文件"); f.deleteOnExit(); System.out.println("删除临时文件"); } catch(IOException e) { System.out.println(e.getMessage()); } } };

Java实用教程

图8.4 临时文件的周期说明

Java实用教程 8.3.4 RandomAccessFile类 RandomAccessFile(随机访问文件)类的实例支持对随机访 问文件的读/写。随机访问文件就像存储在文件系统中的巨大的 字节数组,通过游标或者索引(叫做文件指示器)指向这个暗含

的数组,输入操作从指示器处读取字节,然后前进指针。如果
随机访问文件以可读/写模式创建,那么还支持输出操作,输出 操作写到暗含数组的尾端,使得数组得以扩展。

Java实用教程 【例8.5】随机访问文件,将文件内容输出,并写入两个字 符“O”、“K”。文件内容显示如图8.5的下半部分所示,若文件

内容直接输出到屏幕上,则出现如图8.5上半部分所示的乱码问
题,添加一个parseChinese方法后,得以修正,输出结果如图8.6 所示。源程序代码如下:

//程序文件名为UseRandom.java
import java.io.*; public class UseRandom { public static void main(String[] args)

{

Java实用教程 try {

//构建随机访问文件对象
RandomAccessFile f = new RandomAccessFile("Hello.txt","rw"); //得到文件指针和长度 long flag = 0; long len = f.length();

//字符处理后输出
while(flag <len) {

Java实用教程 String s = f.readLine(); System.out.println(parseChinese(s)); flag = f.getFilePointer(); } //末尾写入字符 f.writeChar('O'); f.writeChar('K'); } catch(IOException e) { System.out.println(e.getMessage()); } }

Java实用教程

//解决中文转换问题
public static String parseChinese(String inStr) {

String s = null;
byte temp[]; if (inStr == null) { return new String(""); } try { temp=inStr.getBytes("iso-8859-1");

Java实用教程 s = new String(temp); }

catch(UnsupportedEncodingException e)
{ System.out.println (e.toString()); } return s;

}
};

Java实用教程

图8.5 文件内容及屏幕输出

Java实用教程

图8.6 字符处理后的屏幕输出

Java实用教程

8.4 对 象 流
8.4.1 ObjectInputStream类

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

Java实用教程 8.4.2 ObjectOutputStream类 ObjectOutputStream(对象输出流)可将Java的原始数据类型

和图形写入输出流,对象可以使用对象输入流读取,使用文件
可以实现对象的持久存储。它的构造函数和一个写对象方法如 下:

public ObjectOutputStream(OutputStream out) throws
IOException

创建一个对象输出流,可以写入特定的输出流。
void writeObject(Object obj)

将对象obj写入对象输出流。

Java实用教程

【例8.6】将日期对象和向量对象写入文件,然后从文件中
读出并输出到屏幕上,输出结果如图8.7所示。要求向量对象含 有三个值“语文”、“数学”和“物理”。源程序代码如下:

//程序文件名为UseStream.java
import java.io.*; import java.util.*; public class UseStream extends Object { public static void main(String[] args) {

Java实用教程 //构建Vector对象 Vector v = new Vector();

v.add("语文");
v.add("数学"); v.add("物理");

try
{ //文件处理对象 File f = new File("temp.txt"); FileOutputStream fOut = new FileOutputStream(f);

ObjectOutputStream objOut = new

Java实用教程 ObjectOutputStream(fOut); //写入日期对象 objOut.writeObject(new Date()); //写入Vector对象 objOut.writeObject(v); objOut.close(); //构建readObj的实例 readObj rObj = new readObj(); //调用方法输出 rObj.readO(); } catch(IOException e) {

Java实用教程 System.out.println(e.getMessage());

}
} }; //自定义类,实现读取对象并输出 class readObj extends Object { public void readO() { try { //文件处理对象 File f = new File("temp.txt");

Java实用教程 FileInputStream fIn = new FileInputStream(f); ObjectInputStream objIn = new ObjectInputStream(fIn);

//读取对象输出
Object ob1 = objIn.readObject(); System.out.println(ob1); Object ob2 = objIn.readObject(); System.out.println(ob2);

}
catch(IOException e) {

Java实用教程 System.out.println(e.getMessage()); }

catch(ClassNotFoundException e)
{ System.out.println(e.getMessage()); } }

};

Java实用教程

图8.7 对象输出

Java实用教程

习 题

1. 编写一个一位数算术表达式计算器,要求用户从命令 提示符下输入表达式,如5*4,程序返回结果5*4 = 20。循环提

示,直至用户输入“$”符号终止程序。【提示:程序解析表达
式,得出操作数和操作符,进行运算后返回结果。】要求程序 交互提示如下:

程序提示:请输入一位数表达式…
用户输入:3+2 程序返回:3+2 = 5 程序提示:请输入一位数表达式… 用户输入:$

程序退出:退出系统

Java实用教程

2. 编写应用程序,界面如图8.8所示。当用户在第一个文本
框内填入文件的路径后单击“打开文件”按钮,文件的内容显 示在下面的文本区域内,在文本区域内对文件做出修改后,单 击“存储文件”按钮,则可以将文件存入原来的文件名中。

图8.8 用户界面

Java实用教程 3. 编写应用程序,界面如图8.8所示,首先在文本框中输入

一个新文件名称,单击“存储文件”按钮时,使用Hashtable对
象存储以下键-值对 语文 89;数学 98;英语 90 并将此Hashtable对象写入“文件名”标识的新文件中,然后单

击“打开文件”按钮,完成以下操作:打开文件,读出对象,
在文本区域中顺序输出分数。

Java实用教程

第9章 Java数据库技术
9.1 JDBC概述 9.2 使用JDBC 9.3 实例 习 题

Java实用教程

9.1 JDBC概述
JDBC(Java Database Connection,Java数据库连接)是一种用 于执行SQL语句的JavaAPI(应用程序设计接口),它由一些Java语 言写的类和界面组成。JDBC提供了一种标准的应用程序设计接

口,使得开发人员使用Java语言开发完整的数据库应用程序变得
极为简单。通过JDBC,开发人员几乎可以将SQL语句传递给任 何一种数据库,而无需为各种数据库编写单独的访问程序。 JDBC可以自动将SQL语句传递给相应的数据库管理系统。

Java实用教程

JDBC扩展了Java的功能,例如在Applet中应用JDBC,可以
实现与远程数据库的连接,实现不同平台数据库之间的对话。 简单地说,JDBC完成下面三个操作: (1) 与一个数据库建立连接。 Connection con = DriverManager.getConnection("jdbc:odbc:CallCenter","sa",""); (2) 向数据库发送SQL语句。

stmt = con.createStatement();
rs = stmt.executeQuery("SELECT CID,CPin from tCustomer

WHERE CID='z1'");

Java实用教程 (3) 处理数据库返回的结果。

while(rs.next())
{ String theInt = rs.getString("CID"); String str = rs.getString("CPin"); ... }

Java实用教程

9.2 使 用JDBC
JDBC的接口分为两个层次:一个是面向程序开发人员的 JDBC API;另外一个是底层的JDBC Driver API。JDBC API 被 描述成为一组抽象的Java接口,应用程序可以对某个数据库打 开连接,执行SQL语句并且处理结果。最重要的接口如下: java.sql.DriverManager:处理驱动的调入并且对产生新的数 据库连接提供支持。 java.sql.Connection:代表对特定数据库的连接。

java.sql.Statement:代表一个特定的容器,以对一个特定的 数据库执行SQL语句。
java.sql.ResultSet:控制对一个特定语句的行数据的存取。

Java实用教程 其中java.sql.Statement又有两个子类型:

(1) java.sql.PreparedStatement:用于执行预编译的SQL语句。
(2) java.sql.CallableStatement:用于执行对一个数据库内嵌过

程的调用。
JDBC Driver API是指java.sql.Driver接口,封装了不同数据库 的驱动程序(像Access、Foxpro、SQL Server等)。由于它是数据库 底层处理,所以必须提供对java.sql.Connection、java.sql. Statement、java.sql.PreparedStatement和java.sql.ResultSet的实现。

Java实用教程 如果目标DBMS提供有OUT参数的内嵌过程,那么还必须 提供java.sql.CallableStatement 接口。在java.sql.Driver接口中每

个数据库驱动程序必须提供一个类,使得系统可以由
java.sql.DriverManager来管理。一个比较好用的驱动程序是在 ODBC之上提供对JDBC的实现,从而提供与ODBC接口的 JDBC-ODBC 桥。所谓JDBC-ODBC桥,是一个JDBC驱动程序, 通过将JDBC操作转换为ODBC操作来实现JDBC操作。它由

sun.jdbc.odbc包实现,包含一个用来访问ODBC的本地库,对所
有ODBC可用的数据库实现JDBC。

Java实用教程 通过ODBC子协议,可以使用下面一行代码进行显示加载。 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 加载时,ODBC驱动程序将创建自己的实例,同时在 JDBC驱动程序管理器中进行注册。由于JDBC放在ODBC之后, 所以实现起来简单且高效。

Java实用教程 9.2.1 Driver Driver接口是每个驱动器类都需要完成的。JavaSQL框架

允许有多个数据库驱动器,每个驱动器应该提供一个类来实现
驱动器接口,而驱动器的装载通过DriverManager实例实现。

DriverManager将装载尽量多的驱动器,对每个给定的连接
请求,将所有的驱动器依次连接到目标数据库上。当驱动器类 装载后,Driver应该创建一个实例,然后注册到DriverManager 上。

Java实用教程 9.2.2 DriverManager DriverManager管理一系列JDBC驱动器的基本服务。应用程

序可以显式加载JDBC驱动器。例如下面代码显式加载
my.sql.Driver。 Class.forName("my.sql.Driver"); 显式加载JDBC-ODBC桥:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Java实用教程

它的较为重要的方法有:
public static Connection getConnection(String url) throws SQLException public static Connection getConnection(String url, Properties info) throws SQLException public static Connection getConnection(String url, String user, String password) throws SQLException 这些方法的功能都是建立一个到给定数据库url的连接。 DriverManager试图从注册的JDBC驱动器序列中选择合适的驱动 器,返回到url的连接。

Java实用教程

其中:
(1) url为数据库url,格式为 jdbc:subprotocol:subname。 (2) info以“标记/数值对”作为连接参数,至少应该包括 user和password属性对。 (3) user指数据库用户(连接以什么身份建立)。 (4) password 是用户的密码。 例如:使用JDBC-ODBC桥建立到ODBC配置的数据库 CallCenter的连接,访问CallCenter数据库的用户名为sa,密码无。 语句行如下:
Connection con = DriverManager.getConnection("jdbc:odbc:CallCenter","sa","");

Java实用教程 9.2.3 Connection 一个Connection(连接)就是一个与特定数据库的会话。在连

接的上下文环境中才可以执行SQL语句和返回结果。Connection
对象的数据库可以提供描述它的表、SQL语法和存储过程等的 信息。它较为重要的方法有: public Statement createStatement() throws SQLException 创建一个Statement对象,用于发送SQL语句到数据库。没 有参数的SQL语句通常使用Statement对象执行。如果希望多次 执行,使用PreparedStatement更为高效。

Java实用教程 public PreparedStatement prepareStatement(String sql) throws SQLException

创建一个PreparedStatement对象,发送参数化SQL语句sql
到数据库。

SQL语句可以预先编译并存储到PreparedStatement语句中。
这个对象可以用来高效地多次执行语句。 其中:参数sql是包含多个“?”参数的SQL语句,“?”表 示输入参数由用户进行设置。

Java实用教程 例如: 创建Statement对象语句如下:

stmt = con.createStatement();
创建PreparedStatement对象语句如下: pstmt = con.prepareStatement("UPDATE Xuesheng SET 班级 = ? WHERE 班级 = ?");

Java实用教程 9.2.4 Statement Statement对象用于执行一个静态的SQL语句并返回它产生

的结果。在缺省情况下,任一时刻每个Statement对象只产生一
个ResultSet集。对数据库希望有不同操作得到结果集时,需要 创建不同的Statement对象。它的较为重要的方法有: public ResultSet executeQuery(String sql) throws SQLException

执行给定的sql语句,返回一个ResultSet对象。

Java实用教程

public int executeUpdate(String sql) throws SQLException
执行给定的sql语句,可以是插入(INSERT)、更新(UPDATE) 或者删除(DELETE)等,也可以是一个空语句,执行DDL语句。 返回值是操作的记录个数。 public ResultSet getResultSet() throws SQLException

以ResultSet对象格式返回当前结果集,每个结果集只调用一次。
例如:

从表tCustomer中返回CID为z1的记录的CID(客户ID)和CPin(密 码)列,语句行为:
rs = stmt.executeQuery("SELECT CID,CPin from tCustomer WHERE CID= 'z1' ");

Java实用教程

9.2.5 PreparedStatement
PreparedStatement代表预编译的SQL语句的对象。一个SQL

语句预编译后存储到PreparedStatement对象中,这个对象用来多
次执行语句。PreparedStatement继承于Statement,扩展了

Statement的用途,提高了Statement的执行效率。它与Statement
对象有两点不同: (1) 同一个对象可以多次使用。 (2) 它的SQL语句可以带输入(IN)参数。

Java实用教程 PreparedStatement在程序语句中的输入参数使用占位符 “?”来实现。必须使用类提供的设置方法设置语句中占位符

的具体值,才能执行语句。如下面的程序段,根据ID的取值
更新EMPLOYEES表中SALARY字段的取值,将第一个占位 符代表的参数设置为10000.00,将第二个占位符代表的参数 设置为111,语句执行的结果是EMPLOYEES表中ID为111的 记录的SALARY取值为10000.00。

Java实用教程
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");

pstmt.setBigDecimal(1, 10000.00)
pstmt.setInt(2, 111); pstmt.executeUpdate();

类PreparedStatement提供的常用方法如下:
public boolean execute() throws SQLException 执行PreparedStatement对象中的任一类型的SQL语句。如果 返回true,则调用getResultSet方法取得ResultSet集;如果返回 false,则调用getUpdateCount方法获得更新数。

Java实用教程 public ResultSet executeQuery() throws SQLException 执行SQL查询,并返回查询产生的结果集。 public int executeUpdate() throws SQLException 执行对象中的SQL语句。如果是一些更新操作,如插入 (INSERT)、修改(UPDATE)和删除(DELETE )等,则返回操作的 个数。

Java实用教程 常用的设置方法为: public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException 在第parameterIndex位置设置BigDecimal型x。 public void setBoolean(int parameterIndex, boolean x) throws SQLException 在第parameterIndex位置设置布尔型x。 public void setByte(int parameterIndex, byte x) throws SQLException 在第parameterIndex位置设置字节型x。

Java实用教程

public void setBytes(int parameterIndex, byte[] x) throws SQLException
在第parameterIndex位置设置字节数组型x。

public void setDouble(int parameterIndex, double x) throws SQLException
在第parameterIndex位置设置双精度型x。 public void setFloat(int parameterIndex, float x) throws SQLException

在第parameterIndex位置设置单精度型x。
public void setInt(int parameterIndex, int x) throws SQLException 在第parameterIndex位置设置整型x。

Java实用教程 public void setLong(int parameterIndex, long x) throws SQLException 在第parameterIndex位置设置长整型x。 public void setNull(int parameterIndex, int sqlType) throws SQLException 在第parameterIndex位置设置为空x。 public void setObject(int parameterIndex, Object x) throws SQLException 在第parameterIndex位置设置对象x。 public void setShort(int parameterIndex, short x) throws SQLException 在第parameterIndex位置设置短整型x。

Java实用教程 void setString(int parameterIndex, String x) throws

SQLException
在第parameterIndex位置设置字符串型x。 public void setTime(int parameterIndex, Time x) throws SQLException 在第parameterIndex位置设置时间型x。

public void setTimestamp(int parameterIndex, Timestamp x)
throws SQLException 在第parameterIndex位置设置时间戳型x。

Java实用教程 9.2.6 ResultSet Result对象是指一张数据表,代表数据库结果集,通常是通

过执行查询数据库的语句而产生的。ResultSet对象持有一个游
标,该游标指向当前数据行。初始化时游标定位到第一行之前。 Next方法将游标移动到下一行,当对象行

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • TP15 Canvas画图

    TP15 Canvas画图

    2016-12-03 11:04

  • Tkinter教程之Canvas篇(3)

    Tkinter教程之Canvas篇(3)

    2016-12-02 14:00

  • 相似辅助线作图技巧大比拼(讲义)王闫闫

    相似辅助线作图技巧大比拼(讲义)王闫闫

    2016-09-28 17:00

  • Android—BitMap与Canvas学习笔记

    Android—BitMap与Canvas学习笔记

    2015-11-21 19:17

网友点评