1
第 2章 Java小应用北京大学计算机系代亚非
2
第 2章 Java小应用
2.1 所有小应用程序的根源
2.2 小试身手
2.3 图形操作
2.4 URL类
2.5 载入现有图像文件
2.6 动画效果
2.7 播放声音
2.8 小 结
3
2.1 所有小应用程序的根源
2.1.1 小应用的特点
回忆一下小应用程序的书写格式
import java.applet.*;
public class MyApplet extends Applet
{ ;}
applet都继承自 java.applet.Applet类,由 Sun公司事先定义好了,
每个小应用都有一个主程序类,之前必须加上
public.
42.1 所有小应用程序的根源
http://someLocation/file.html 1,Browser loads URL
<Html>
<Applet code= ….>
</Applet>
2,Browser loads
HTML document
Applet class
3,Browser loads
applet classes
Location,http://someLocation/file.html
Loading...
4,Browser
run applet
5
2.1 所有小应用程序的根源
Applet的限制
applet
BrowserSERVER 本地程序
file
SERVER
local
Applet被下载的与 applet无关的本地方法
6
2.1 所有小应用程序的根源
2.1.2 applet的生命周期
paint()虽不在生命周期内,但它的作用相当于
applet的灵魂
Java.applet.Applet
public void init() public void destroy()
public void start() public void stop()
public void paint(Graphics g)
7
2.1 所有小应用程序的根源
一个 applet的可视周期
init
start
stop
destroy
离开 web页面 重新装入或改变页面大小或返回 Web页面
8
2.1 所有小应用程序的根源
有关 paint()方法
Applet本身是一个容器,因此任何输出都必须用图形方法 paint()
当小应用首次被装载,以及每次窗口放大、
缩小、刷新时都要调用 paint方法
paint()是由浏览器调用的,而不是由程序调用,
当程序希望调用 paint方法时,用 repaint命令
paint方法的参数是 Graphics类的对象 g,它在 java.awt.Graphics内
paint( Graphicd g) {。。。 }
9
2.1 所有小应用程序的根源
AWT thread( waiting)
update()
{ clear arae
call paint()
paint()
repaint() Exposure
10
2.2 小试身手
2.2.1 起始页上的时间和日期
介绍两个类,
1,类名,Date
创建一个实例 Date timeNow=new Date();
2,类名 Font
创建一个实例 Font msgFont=new
Font(“TimesRoman”,Font.ITALIC,30);
0Mon Dec 07 14:23:50 GMT+08:00 1998
11
2.2 小试身手看下面的例子,想一想生命周期的四个方法哪去了?
import java.awt.*; import java.util.Date;
public class showDate extends java.applet.Applet
{ Date timeNow=new Date();
Font msgFont=new
Font(“TimesRoman”,Font.ITALIC,30);
public void paint(Graphics g)
{ g.setFont(msgFont);
g.setColor(Color.blue);
g.darwString(timeNow.toString(),5,50);
}
12
2.2 小试身手
2.2.2 在起始页中加入 applet
html中有关的代码
<APPLET CODE=“showdate.class”
width=600 height=80> </APPLET>
CODEBASE的作用当 class文件与起始页文件不在同一个目录下时,使用 CODEBASE说明
<APPLET CODE=“showdate.class”
width=600 height=80>
CODEBASE=“\myjava\class”</APPLET>
13
2.2 小试身手
<APPLET
CODE=“showdate.class”
width=600 height=80>
CODEBASE=“\myjava\class”
</APPLET>
C:\
public
Index.html
myjava
class
showdate
javacode
C:\
public
Index.html
myjava
class
showdate
javacode
<APP
=“sho date.class”
idth=600 height=80>
</APPLET>
14
2.2 小试身手
ALIGN,HSPACE,VSPACE
Java applet
其它文字其它文字
vspace
hs
pac
e
<APPLET
CODE=“showdate.class” width=600 height=80>
vspace=100 hspace=100
</APPLET>
15
2.2 小试身手
向 applet传递参数的两个步骤
1,在起始页中要有 <PARAM>标签
2,在 applet中要有 getParameter方法在起始页中有,
<applet code=showdate width=600 heigt=80>
<param name=remvalue=“时间是,,></applet>
在 applet中有,
string title=getParameter(rem);
在显示时间的命令中加入 title:
g.drawString(title+timeNow.toString(),5,50);
16
2.2 小试身手
import java.awt.*; import java.util.Date;
public class showDate extends java.applet.Applet
{ Date timeNow=new Date(); String title;
Font msgFont=new
Font(“TimesRoman”,Font.ITALIC,30);
public void init()
{title=getParameter
(“rem”);
if (title==null)
title=“”;
}
public void paint(Graphics g)
{ g.setFont(msgFont);
g.setColor(Color.blue);
g.darwString(title+
timeNow.toString(),5,50);
}
17
2.2 小试身手
例,利用一个可以显示运行字符串的类,显示自己的字符串 (htmlpara.html)
<applet code=htmlpara.class width=300 heigh=200>
<param name=MESSAGE value=”this is a test">
<param name=FONT value="BOLD">
<param name=POINT_SIZE value=20></applet>
18
2.2 小试身手
public void init()
{ String paramete;
parameter=getParameter("MESSAGE");
if (parameter!=null)
message=parameter;
parameter=getParameter("FONT");
if (parameter!=null)
font_to_use=parameter;
parameter=getParameter("POINT_SIZE");
if (parameter!=null)
point_size=Integer.parseInt(parameter);
}
19
2.3 图形处理
2.3.1图形坐标系统任何与绘图有关的操作第一个要用的是
java.awt.Graphics类
Graphics类的对象不是由 new产生的,而是由系统或其他方式直接将生好的 Graphics对象当作方法的参数,再交给程序设计者去处理,例如,
paint(Graphics g)
x
y
0
20
2.3 图形处理
Graphics的方法
paint(Graphics g)
{ g.clearRect(); g.copyArea(); g.drawAre() ;
g.drawLine(); g.drawOval();g.drawRect();
g.drawPolygon(); g.fillArc(); g.fillOval();
g.fillPolygen(); g.fillRect(); g.getColor();
g.getFont() g.setFont(); g.setColor();
g.getFontMetrics()
g.fillRoundRect()
}
21
2.3 图形处理
2.3.2 字型和颜色的设置
2.3.2.1 字型设置的方法
Font font=new
Font(“TimesRoman”,Font.ITALIC,24);
g.setFont(font);
在小应用程序中显示输出的方法
g.drawString(String,int x,int y);
g.drawChars(char data[],int offset,int length,
int x,int y);
22
2.3 图形处理
g.drawBytes(byte data[],int offset,int length,
int x,int y);
例,g.drawString(“This is a test”,5,10);
获取字体的属性
Font font=g.getFont();
Font类中常用的方法
GetFamily() getName() getSize() getStyle()
isItalic() isPlain() isBold() toString()
23
2.3 图形处理
import java.awt.Graphics; import java.awt.Font;
public class drawtext extends java.applet.Applet
{ Font fn=new Font("TimesRoman",Font.ITALIC,20);
public void paint(Graphics g)
{ g.setFont(fn);
g.drawString(”Font demo”,5,10);
}
}
Font demo
24
2.3 图形处理
获取更详细的数据请查阅有关 FontMetrics类的方法
fontMetrics=getFontMetrics(font);
FontMetrics中比较重要的方法有,
stringWidth,charWidth,getAscent,getDescent,
getLeading,getHeigh
25
2.3 图形处理
2.3.2.2 颜色的调整
Color对象的使用创造自己的颜色,
Color mycolor=new Color(int red,int blue,int green);
g.setColor(Color.yellow)
g.setColor(mycolor);
例,随机产生颜色,并画圆
26
2.3 图形处理
import java.awt.Graphics; import java.awt.Color;
public class drawcircle extends java.applet.Applet {
public void paint(Graphics g) {
int red,green,blue,x;
for (x=0;x<370;x+=30){
red=(int)Math.floor(Math.random()*256);
green=(int)Math.floor(Math.random()*256);
blue=(int)Math.floor(Math.random()*256);
g.setColor(new Color(red,green,blue));
g.fillOval(x,0,30,30); }}}
27
2.4 URL类
2.4.2 构造 URL类 (全名 java.lang.URL)
绝对 URL的构造方法,
URL(String spec)
例,URL url=new URL
(http://www.hit.edu.cn/cv/index.html”)
相对 URL的构造方法,
某绝对地址,http://rainy.hit.edu.cn/test.html
在该目录下有两个文件
mywork.html myfamily.html
28
2.4 URL类
URL base=new URL(“http://rainy.hit.edu.cn”);
URL url1=new (base,“mywork.html”);
URL url2=new (base,“mywork.html”);
其他 URL的构造方法,
URL url=new URL
(“http”,“www.hit.edu.cn”,“/~dyf/test.html”);
29
2.4 URL类
2.4.3 获取小应用程序 HTML页面的 URL和小应用程序本身的 URL
URL html=getDocumentBase();
System.out.print(html);
URL codebase=getCodeBase();
System.out.print(codebase);
浏览器 服务器
html
applet
web page
30
2.4 URL类
2.4.4 URL异常 (MalformedURLException)
当创建 URL时发生错误,系统会产生异常
try{ URL url=new URL(str);
}catch(MalformedURLException( e)
{ DisplayErrorMessage();}
2.4.5 URL类的基本方法
String getProtocol(),String getHost(),
ing getPort(),String getFile(),
String getRef()
31
2.4 URL类
构造 URL的实例
import java.net.URL;
import java.net.MalformedURLException;
public class Test
{ URL url1,url2,url3;
void test()
{ try { url1= new URL(“file:/D:/image/example.gif”);
url2= new URL(“http://www.hit.edu.cn/cv/”);
url1= new URL(url2,“hit.gif”);
}catch (MalformedURLException e);
//处理例外
} }}
32
2.5 载入现有图像文件
Image类
java支持 gif和 jpg两种格式的图像
图像文件的 URL:
URL picurl= new URL
(“http://xxx.yyy.edu/Applet/img1.gif”);
取一幅图像构成图像对象
Image img1 = getImage(picurl);
Image img2 =
getImage(getCodeBase(),“img2.gif”);
33
2.5 载入现有图像文件
显示一幅图像,
g.drawImage(img1,x,y,this);
g.drawImage(img1,x,y,Color.red,this);
g.drawImage(image1,x,y,x2,y2,Color.red,this);
规定背景规定尺寸
34
2.5 载入现有图像文件
完整的过程不要忘记 AWT包定义 Image对象了吗?
指定图像的 URL了吗?
把图像取出来吧,
还记得画图像用什么方法和命令吗?
在类中在 init0中在 paint0中
35
2.5 载入现有图像文件
import java.applet.*;import java.awt.*;
public class image extends Applet
{ Image img;
public void init()
{ img=getImage(getCodeBase(),"img0001.gif");}
public void paint(Graphics g)
{ int width=img.getWidth(this);
int height=img.getHeight(this);
g.drawRect(52,52,width+30,height+30);
g.drawImage(img,57,57,width+20,height+20,this);}}
36
2.6 动态效果 ---线程的应用
2.4 动态效果 ---线程的应用
什么是线程?
线程是执行中的程序中的单个顺序控制流,
Java支持多线程 开始显示进度引出最后结果数学运算线程 1 线程 2
37
2.6 动态效果 ---线程的应用
静态的情况
import java.applet.*;
import java.awt.Graphics;
public class maguee extends Applet
{ public void paint(Graphics g)
{
g.drawString("Hello,Java!",0,0);
}
}
38
2.6 动态效果 ---线程的应用
动态的情况 (不是多线程 )
public void init()
{ x=size().width; y=size().height/2;
width=x;
}
public void paint(Graphics g)
{ while(true)
{ g.drawString("Hello,Java!",x,y);
x-=10;
if(x<0) x=width; }
}
39
2.6 动态效果 ---线程的应用
实现一个线程让 Applet类去实现 Runable接口,创建一个线程类改写方法 start,在其中产生一个新的线程来工作改写 stop方法,在其中编写结束线程的程序代码引入新的方法,将分给线程的工作写到 run中
40
2.6 动态效果 ---线程的应用第一步:实现 Runable接口
public class xc extends java.applet.Applet
implements Runnable
{ Thread smallthread=null;

}
Thread是一个类,只有是它的实例才能具有线程的功能主函数中要定义一个线程变量
41
2.6 动态效果 ---线程的应用第二步:改写方法 start
public void start()
{ if( smallthread == null)
{ smallthread= new Thread( this);
smallthread.start();
//从现在开始程序由两个线程在执行
}}
第三步:改写 stop方法
public void stop()
{ smallthread.stop(); //停止线程
smallthread = null; //释放线程对象 }
42
2.6 动态效果 ---线程的应用第四步,新的方法 run
将让线程要做的事放 run中
public void run()
{ while (true) {
repaint();
try {Thread.sleep(1000);}
catch(InterruptedException e){}
}
}
43
2.6 动态效果 ---线程的应用
import java.applet.*; import java.awt.Graphics;
public class MovingCharacter extends Applet implements Runnable
{ int x=200;
Thread my_thread=null;
//-------------------------------------------------
public void start()
{ my_thread=new Thread(this);
my_thread.start();
}
public void run()
{ while(true)
{ repaint();
try { Thread.sleep(100);
} catch(InterruptedException e){}
}}
44
2.6 动态效果 ---线程的应用
,
public void paint(Graphics g)
{ g.drawString("Hello,Java!",x,y);
x-=10;
if(x<0) x=200;
}
public void stop()
{ my_thread.stop(); }
45
2.6 动态效果 ---线程的应用
跳动的小球
up=false;
x=x-10; if(x<0) x=width;
if (up) y=y+10;else y=y-10;
if (y<0) up=true;
if (y>height) up=false;
g.setColor(Color.red);
g.fillOval(x,y,30,30);
46
2.6 动态效果 ---线程的应用例,起始页上的小时钟一个必须用到的类 ----Date类,给出系统时间
Date NowTime=new Date();
NowTime.getHours(),
NowTime.getMinutes()
自己需要写什么样的类?
Clock---把数字时间成图形表示
(Hour*60*60+minute*60+second)/43200*2.0*PI
(minute*60+second)/3600*2.0*PI
second/60*2.0*PI
47
2.6 动态效果 ---线程的应用取时间 paint() {}
主类换算弧度 画图
clock类
clock(){}
初始化
Show(){} drawNiddle(){}
48
2.6 动态效果 ---线程的应用class Clock
{int hours,minutes,second,radius;
Clock(int hrs,int min,int sec)
{ hours=hrs%12; minutes=min; second=sec; }
void show(Graphics g,int x,int y,int redius)
{ int hrs_len=(int)(radius*0.5);
int min_len=(int)(radius*0.7);
int sec_len=(int)(radius*0.85);
double theta;
g.drawOval(x,y,radius*2,radius*2);
49
2.6 动态效果 ---线程的应用theta=(double)(hours*60*60+minutes*60+second)/
43200.0*2.0*Math.PI;
drawNiddle(g,Color.blue,x,y,hrs_len,theta);
theta=(double)(minutes*60-second)/3600.0*2.0*Math.PI;
drawNiddle(g,Color.blue,x,y,min_len,theta);
theta=(double)second/60.0*2.0*Math.PI;
drawNiddle(g,Color.red,x,y,sec_len,theta);
}
50
2.6 动态效果 ---线程的应用
private void drawNiddle(Graphics g,
Color c,int x,int y,int len,double theta)
{ g.setColor(c);
g.drawLine(x,y,(int)(x+len*Math.sin(theta)),
(int)(y-len*Math.cos(theta))); }
}
51
2.6 动态效果 ---线程的应用import java.awt.*;import java.util.Date;
public class ClockDemo extends java.applet.Applet
{ public void paint()
{ Date timeNow = new Date();
Clock myClock = new
Clock(timeNow.getHours(),
timeNow.getMinutes(),
timeNow.getSeconds());
myClock.show(g,100,100,100);
}
}
52
2.6 动态效果 ---线程的应用生成时间对象,取时间生成 Clock对象,将时间传递给 Clock对象
paint() {}
主类换算弧度 画图
clock类
clock(){}
初始化
Show(){} drawNiddle(){}
53
2.6 动态效果 ---线程的应用主类
start() stop() run()paint()
换算弧度 画图
clock类
clock(){}
初始化
Show(){} drawNiddle(){}
启动新线程 停止线程 生成 clock类实例 repaint()
54
2.6 动态效果 ---线程的应用例,在主页上显示 字符串并且颜色从左至右不断变化让我们来想一想,需要那些数据成员?
String msg,Font fnt,Color clr,spot_clr;
Thread thread;
String Msg="Welcome to HIT";
需要哪些方法? init,start,stop,run,paint;
public void init()
{ fnt= new Font("TimeRoman",Font.PLAIN,30);
clr=new Color(255,0,0);
spot_clr=new Color(0,0,255);
Thread thread;}
55
2.6 动态效果 ---线程的应用
run()中做什么? 反复调用 repaint
public void run()
{ while(true)
{ repaint();
try{Thread.sleep(50);}
catch(InterruptedException e) {}
}
}
56
2.6 动态效果 ---线程的应用
paint()中做什么?
输出两次字符串,第一次用一种颜色,第二次用另一种颜色 (该颜色只作用于指定的区域 )
g.clipRect(x,y,width,height)
public void paint(Graphics g)
{ FontMetrics fntM=g.getFontMetrics();
int font_height=fntM.getHeight();
int base_line=size().height/2+font_height/2;
You are Welcome to HIT
57
2.6 动态效果 ---线程的应用
g.setFont(fnt);
g.setColor(clr);
g.drawString(Msg,0,base_line);
g.clipRect(strPt-50,0,str_bk_size,size().height);
g.setColor(spot_clr);
g.drawString(Msg,0,base_line);
strPt=(strPt+1)%(size().width+100);
}
}
58
2.6 动态效果 ---线程的应用在 Java中播放动画
1.需要多张图片
2 调用图片的方法? getImage,
3.将多幅图像存入图像对象数组
Image frame[]=new Image[10];
for (int i=0;i<frame.length;i++)
frame[i]=getImage(getCodeBase(),“pic”+i+,.gif”);
4,显示图像 drawImage(x,y,0,0,this),
59
2.6 动态效果 ---线程的应用
import java.awt.*;
public class nina extends java.applet.Applet
implements Runnable
{Image frame[];
Thread threadNina; int frame_i; int delay_time;
public void init()
{ frame=new Image[10];
threadNina=null; frame_i=0;
for (int i=0;i<frame.length;i++)
frame[i]=getImage(getCodeBase(),"pic"+i+ ".gif");
}
60
2.6 动态效果 ---线程的应用
public void paint(Graphics g)
{ g.drawImage(frame[frame_i],0,0,this);}
public void run()
{ while(true)
{ repaint();
try{ Thread.sleep(100);}
catch(InterruptedException e) {}
frame_i=(frame_i+1)%frame.length;
}
}
61
2.7 播放声音
java支持 au格式的声音两个方法,
void play(URL url)
void play(URL url,String name)
例,play(getCodeBase(),“boing.au”);
(注,它是一次性的 )
如果想反复播放怎么办?
借用类 AudioClip(loop(),play(),stop())
62
2.7 播放声音例,AudioClip bg_sound=
getAudioClip(getCodeBase(),“boing.au”);
bg_sound.play();
或,bg_sound.loop();
import java.applet.AudioClip;
public class audio extends java.applet.Applet
{AudioClip
sound=getAudioClip(getCodeBase(),"boing.au");
public void start()
{ my_sound.loop(); }
public void stop(){
{ if(my_sound!=null) my_sound.stop();}}
63
2.7 播放声音
图像加声音岂不是更有吸引力
1,在 init中既取图像也取声音片断
frame[i]=getImage(getCodeBase(),
"img000"+i+".gif");
SoundClip=getAudioClip(getCodeBase(),"boing.au");
2,在 init中加入
SoundClip.loop();
3,在 stop中加入
if (SoundClip!=null) SoundClip.stop();
64
2.8 可通用的代码
同时包含 main()方法和 init()方法
由于 application本身不是图形环境,因此需要在程序中加入图形环境,以便可以作为普通的
application使用
import java.applet.Applet; import java.awt.*;
import java.awt.event.*;
import java.util.*;
65
2.9 小结
小应用程序是在浏览器中运行的,每个小应用程序中必须有一个主类,冠以 public,并且继承自
java.applet.
小应用程序包括生命周期的四个环节和 paint()
根据程序要求,用户可以在主类中定义其它方法,
或定义其它类,
public class myapplet extends Applet
{ init() {…};start() {…};
stop() {…};destroy() {…};
paint(Graphics g){…}
}
myclass1{…..};class myclass2{…};
66
2.9 小结applet
主类
init()
start()
paint()
stop()
destroy()
自定义方法
applet启动后第一个被执行,在此初始化
init()后被执行,程序主要代码写在此
start()后被执行,写与输出有关的代码浏览器变换页面时执行,可以省略重写浏览器关闭时执行,可以省略重写不能自动被执行,可以由前三个方法调用,例如,start()
{ mymethod()}
Classes
mymethod1
mymethode2
Classes myclass =new Classes()
myclass.method1();
.
.
67
2.9 小结class Myclass
{ int v1;
method(int num)
{v1=num;}
}
test1
public class Demo extends Applet
{ public void init()
{ Myclass test1=new Myclass();
test1.method(20);
Myclass test2=new Myclass();
test2.method(10); }
}
v1
test2
v1
20
10
内存
68
2.9 小结
线程是实现动态效果的核心,运行线程必须继承 Thread类或者实现 Runable接口,
run 是线程的主体,它反复调用 repaint()方法,
其中必须有休眠 sleep().
sleep()语句要捕获中断异常 (右面讲 )
try{Thread.sleep(100);}
catch(InterruptedException e) {}
有线程的小应用,start(),stop()方法必须重写,
需要获取网络资源时 (包括本地资源 ),要用
URL类