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 类 , 由 Su
n 公司事先定义好了 .• 每个小应用都有一个主程序类 , 之前必须加上 public.
42.1 所有小应用程序的根源http://someLocation/file.html 1. Browser loads URL
<Html><Applet code= ….></Applet>
2. Browser loads HTML document
Applet class3. Browser loads applet classes
Location: http://someLocation/file.html
Loading...
4. Browser run applet
5
2.1 所有小应用程序的根源• Applet 的限制
applet
BrowserSERVER本地程序
file
SERVERlocal
connection
connection
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
<APPLET CODE=“showdate.class” width=600 height=80></APPLET>
14
2.2 小试身手• ALIGN,HSPACE,VSPACE
Java applet
其它文字
其它文字vspace
hspace
<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=rem value=“ 时间是 : ”></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 动态效果 ---线程的应用第二步:改写方法 startpublic 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() 中做什么 ? 反复调用 repaintpublic 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, 并且继承自 j
ava.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() 方法必须重写 .• 需要获取网络资源时 (包括本地资源 ), 要用 UR
L 类
Recommended